35#include "llvm/ADT/IndexedMap.h"
36#include "llvm/ADT/PointerEmbeddedInt.h"
37#include "llvm/ADT/STLExtras.h"
38#include "llvm/ADT/SmallSet.h"
39#include "llvm/ADT/StringExtras.h"
40#include "llvm/Frontend/OpenMP/OMPAssume.h"
41#include "llvm/Frontend/OpenMP/OMPConstants.h"
45using namespace llvm::omp;
58enum DefaultDataSharingAttributes {
63 DSA_firstprivate = 1 << 3,
73 unsigned Modifier = 0;
74 const Expr *RefExpr =
nullptr;
77 bool AppliedToPointee =
false;
78 DSAVarData() =
default;
82 bool AppliedToPointee)
83 : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr),
84 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc),
85 AppliedToPointee(AppliedToPointee) {}
87 using OperatorOffsetTy =
89 using DoacrossDependMapTy =
90 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>;
92 enum class UsesAllocatorsDeclKind {
104 unsigned Modifier = 0;
107 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
111 bool AppliedToPointee =
false;
113 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
114 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
115 using LCDeclInfo = std::pair<unsigned, VarDecl *>;
116 using LoopControlVariablesMapTy =
117 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
120 struct MappedExprComponentTy {
124 using MappedExprComponentsTy =
125 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
126 using CriticalsWithHintsTy =
127 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
128 struct ReductionData {
129 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
131 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
132 ReductionData() =
default;
139 ReductionOp = RefExpr;
142 using DeclReductionMapTy =
143 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
144 struct DefaultmapInfo {
148 DefaultmapInfo() =
default;
150 : ImplicitBehavior(M), SLoc(Loc) {}
153 struct SharingMapTy {
154 DeclSAMapTy SharingMap;
155 DeclReductionMapTy ReductionMap;
156 UsedRefMapTy AlignedMap;
157 UsedRefMapTy NontemporalMap;
158 MappedExprComponentsTy MappedExprComponents;
159 LoopControlVariablesMapTy LCVMap;
160 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
165 Scope *CurScope =
nullptr;
171 DoacrossDependMapTy DoacrossDepends;
176 unsigned AssociatedLoops = 1;
177 bool HasMutipleLoops =
false;
178 const Decl *PossiblyLoopCounter =
nullptr;
179 bool NowaitRegion =
false;
180 bool UntiedRegion =
false;
181 bool CancelRegion =
false;
182 bool LoopStart =
false;
183 bool BodyComplete =
false;
188 Expr *TaskgroupReductionRef =
nullptr;
197 llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind>
201 struct ImplicitDefaultFDInfoTy {
205 size_t StackLevel = 0;
208 ImplicitDefaultFDInfoTy(
const FieldDecl *FD,
size_t StackLevel,
210 : FD(FD), StackLevel(StackLevel), VD(VD) {}
214 ImplicitDefaultFirstprivateFDs;
215 Expr *DeclareMapperVar =
nullptr;
218 :
Directive(DKind), DirectiveName(Name), CurScope(CurScope),
220 SharingMapTy() =
default;
226 DeclSAMapTy Threadprivates;
233 bool ForceCapturing =
false;
236 bool ForceCaptureByReferenceInTargetExecutable =
false;
237 CriticalsWithHintsTy Criticals;
238 unsigned IgnoredStackElements = 0;
242 using const_iterator = StackTy::const_reverse_iterator;
243 const_iterator begin()
const {
244 return Stack.empty() ? const_iterator()
245 : Stack.back().first.rbegin() + IgnoredStackElements;
247 const_iterator end()
const {
248 return Stack.empty() ? const_iterator() : Stack.back().first.rend();
250 using iterator = StackTy::reverse_iterator;
252 return Stack.empty() ? iterator()
253 : Stack.back().first.rbegin() + IgnoredStackElements;
256 return Stack.empty() ? iterator() : Stack.back().first.rend();
261 bool isStackEmpty()
const {
262 return Stack.empty() ||
263 Stack.back().second != CurrentNonCapturingFunctionScope ||
264 Stack.back().first.size() <= IgnoredStackElements;
266 size_t getStackSize()
const {
267 return isStackEmpty() ? 0
268 : Stack.back().first.size() - IgnoredStackElements;
271 SharingMapTy *getTopOfStackOrNull() {
272 size_t Size = getStackSize();
275 return &Stack.back().first[
Size - 1];
277 const SharingMapTy *getTopOfStackOrNull()
const {
278 return const_cast<DSAStackTy &
>(*this).getTopOfStackOrNull();
280 SharingMapTy &getTopOfStack() {
281 assert(!isStackEmpty() &&
"no current directive");
282 return *getTopOfStackOrNull();
284 const SharingMapTy &getTopOfStack()
const {
285 return const_cast<DSAStackTy &
>(*this).getTopOfStack();
288 SharingMapTy *getSecondOnStackOrNull() {
289 size_t Size = getStackSize();
292 return &Stack.back().first[
Size - 2];
294 const SharingMapTy *getSecondOnStackOrNull()
const {
295 return const_cast<DSAStackTy &
>(*this).getSecondOnStackOrNull();
304 SharingMapTy &getStackElemAtLevel(
unsigned Level) {
305 assert(Level < getStackSize() &&
"no such stack element");
306 return Stack.back().first[Level];
308 const SharingMapTy &getStackElemAtLevel(
unsigned Level)
const {
309 return const_cast<DSAStackTy &
>(*this).getStackElemAtLevel(Level);
312 DSAVarData getDSA(const_iterator &Iter,
ValueDecl *D)
const;
315 bool isOpenMPLocal(
VarDecl *D, const_iterator Iter)
const;
328 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
337 explicit DSAStackTy(
Sema &S) : SemaRef(S) {}
340 void setOMPAllocatorHandleT(
QualType Ty) { OMPAllocatorHandleT = Ty; }
342 QualType getOMPAllocatorHandleT()
const {
return OMPAllocatorHandleT; }
344 void setOMPAlloctraitT(
QualType Ty) { OMPAlloctraitT = Ty; }
346 QualType getOMPAlloctraitT()
const {
return OMPAlloctraitT; }
348 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
350 OMPPredefinedAllocators[AllocatorKind] = Allocator;
353 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind)
const {
354 return OMPPredefinedAllocators[AllocatorKind];
357 void setOMPDependT(
QualType Ty) { OMPDependT = Ty; }
359 QualType getOMPDependT()
const {
return OMPDependT; }
362 void setOMPEventHandleT(
QualType Ty) { OMPEventHandleT = Ty; }
364 QualType getOMPEventHandleT()
const {
return OMPEventHandleT; }
366 bool isClauseParsingMode()
const {
return ClauseKindMode != OMPC_unknown; }
368 assert(isClauseParsingMode() &&
"Must be in clause parsing mode.");
369 return ClauseKindMode;
373 bool isBodyComplete()
const {
374 const SharingMapTy *Top = getTopOfStackOrNull();
375 return Top && Top->BodyComplete;
377 void setBodyComplete() { getTopOfStack().BodyComplete =
true; }
379 bool isForceVarCapturing()
const {
return ForceCapturing; }
380 void setForceVarCapturing(
bool V) { ForceCapturing =
V; }
382 void setForceCaptureByReferenceInTargetExecutable(
bool V) {
383 ForceCaptureByReferenceInTargetExecutable =
V;
385 bool isForceCaptureByReferenceInTargetExecutable()
const {
386 return ForceCaptureByReferenceInTargetExecutable;
391 assert(!IgnoredStackElements &&
392 "cannot change stack while ignoring elements");
394 Stack.back().second != CurrentNonCapturingFunctionScope)
395 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
396 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
397 Stack.back().first.back().DefaultAttrLoc = Loc;
401 assert(!IgnoredStackElements &&
402 "cannot change stack while ignoring elements");
403 assert(!Stack.back().first.empty() &&
404 "Data-sharing attributes stack is empty!");
405 Stack.back().first.pop_back();
410 class ParentDirectiveScope {
415 ParentDirectiveScope(DSAStackTy &Self,
bool Activate)
416 : Self(Self), Active(
false) {
420 ~ParentDirectiveScope() { disable(); }
423 --Self.IgnoredStackElements;
429 ++Self.IgnoredStackElements;
438 "Expected loop-based directive.");
439 getTopOfStack().LoopStart =
true;
444 "Expected loop-based directive.");
445 getTopOfStack().LoopStart =
false;
448 bool isLoopStarted()
const {
450 "Expected loop-based directive.");
451 return !getTopOfStack().LoopStart;
454 void resetPossibleLoopCounter(
const Decl *D =
nullptr) {
455 getTopOfStack().PossiblyLoopCounter = D ? D->getCanonicalDecl() : D;
458 const Decl *getPossiblyLoopCunter()
const {
459 return getTopOfStack().PossiblyLoopCounter;
462 void pushFunction() {
463 assert(!IgnoredStackElements &&
464 "cannot change stack while ignoring elements");
466 assert(!isa<CapturingScopeInfo>(CurFnScope));
467 CurrentNonCapturingFunctionScope = CurFnScope;
471 assert(!IgnoredStackElements &&
472 "cannot change stack while ignoring elements");
473 if (!Stack.empty() && Stack.back().second == OldFSI) {
474 assert(Stack.back().first.empty());
477 CurrentNonCapturingFunctionScope =
nullptr;
479 if (!isa<CapturingScopeInfo>(FSI)) {
480 CurrentNonCapturingFunctionScope = FSI;
486 void addCriticalWithHint(
const OMPCriticalDirective *D, llvm::APSInt Hint) {
487 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint);
489 const std::pair<const OMPCriticalDirective *, llvm::APSInt>
491 auto I = Criticals.find(Name.getAsString());
492 if (I != Criticals.end())
494 return std::make_pair(
nullptr, llvm::APSInt());
511 const LCDeclInfo isLoopControlVariable(
const ValueDecl *D)
const;
516 const LCDeclInfo isParentLoopControlVariable(
const ValueDecl *D)
const;
521 const LCDeclInfo isLoopControlVariable(
const ValueDecl *D,
522 unsigned Level)
const;
525 const ValueDecl *getParentLoopControlVariable(
unsigned I)
const;
528 void markDeclAsUsedInScanDirective(
ValueDecl *D) {
529 if (SharingMapTy *Stack = getSecondOnStackOrNull())
530 Stack->UsedInScanDirective.insert(D);
534 bool isUsedInScanDirective(
ValueDecl *D)
const {
535 if (
const SharingMapTy *Stack = getTopOfStackOrNull())
536 return Stack->UsedInScanDirective.contains(D);
542 DeclRefExpr *PrivateCopy =
nullptr,
unsigned Modifier = 0,
543 bool AppliedToPointee =
false);
552 const Expr *ReductionRef);
558 Expr *&TaskgroupDescriptor)
const;
563 const Expr *&ReductionRef,
564 Expr *&TaskgroupDescriptor)
const;
567 Expr *getTaskgroupReductionRef()
const {
568 assert((getTopOfStack().
Directive == OMPD_taskgroup ||
572 "taskgroup reference expression requested for non taskgroup or "
573 "parallel/worksharing directive.");
574 return getTopOfStack().TaskgroupReductionRef;
578 bool isTaskgroupReductionRef(
const ValueDecl *VD,
unsigned Level)
const {
579 return getStackElemAtLevel(Level).TaskgroupReductionRef &&
586 const DSAVarData getTopDSA(
ValueDecl *D,
bool FromParent);
588 const DSAVarData getImplicitDSA(
ValueDecl *D,
bool FromParent)
const;
590 const DSAVarData getImplicitDSA(
ValueDecl *D,
unsigned Level)
const;
597 DefaultDataSharingAttributes)>
600 bool FromParent)
const;
608 bool FromParent)
const;
615 unsigned Level,
bool NotLastprivate =
false)
const;
619 bool hasExplicitDirective(
621 unsigned Level)
const;
625 const llvm::function_ref<
bool(
628 bool FromParent)
const;
632 const SharingMapTy *Top = getTopOfStackOrNull();
633 return Top ? Top->Directive : OMPD_unknown;
637 assert(!isStackEmpty() &&
"No directive at specified level.");
638 return getStackElemAtLevel(Level).Directive;
642 unsigned OpenMPCaptureLevel)
const {
645 return CaptureRegions[OpenMPCaptureLevel];
649 const SharingMapTy *
Parent = getSecondOnStackOrNull();
654 void addRequiresDecl(
OMPRequiresDecl *RD) { RequiresDecls.push_back(RD); }
657 template <
typename ClauseType>
bool hasRequiresDeclWithClause()
const {
660 return isa<ClauseType>(C);
668 bool IsDuplicate =
false;
671 for (
const OMPClause *CPrev : D->clauselists()) {
672 if (CNew->getClauseKind() == CPrev->getClauseKind()) {
673 SemaRef.
Diag(CNew->getBeginLoc(),
674 diag::err_omp_requires_clause_redeclaration)
675 << getOpenMPClauseName(CNew->getClauseKind());
676 SemaRef.
Diag(CPrev->getBeginLoc(),
677 diag::note_omp_requires_previous_clause)
678 << getOpenMPClauseName(CPrev->getClauseKind());
689 TargetLocations.push_back(LocStart);
695 AtomicLocation = Loc;
700 SourceLocation getAtomicDirectiveLoc()
const {
return AtomicLocation; }
704 return TargetLocations;
709 getTopOfStack().DefaultAttr = DSA_none;
710 getTopOfStack().DefaultAttrLoc = Loc;
714 getTopOfStack().DefaultAttr = DSA_shared;
715 getTopOfStack().DefaultAttrLoc = Loc;
719 getTopOfStack().DefaultAttr = DSA_private;
720 getTopOfStack().DefaultAttrLoc = Loc;
724 getTopOfStack().DefaultAttr = DSA_firstprivate;
725 getTopOfStack().DefaultAttrLoc = Loc;
730 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind];
731 DMI.ImplicitBehavior = M;
737 return getTopOfStack()
738 .DefaultmapMap[OMPC_DEFAULTMAP_aggregate]
741 .DefaultmapMap[OMPC_DEFAULTMAP_scalar]
744 .DefaultmapMap[OMPC_DEFAULTMAP_pointer]
746 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior !=
751 return ConstructTraits;
756 ConstructTraits.append(Traits.begin(), Traits.end());
758 for (llvm::omp::TraitProperty Trait : llvm::reverse(Traits)) {
759 llvm::omp::TraitProperty Top = ConstructTraits.pop_back_val();
760 assert(Top == Trait &&
"Something left a trait on the stack!");
766 DefaultDataSharingAttributes getDefaultDSA(
unsigned Level)
const {
767 return getStackSize() <= Level ? DSA_unspecified
768 : getStackElemAtLevel(Level).DefaultAttr;
770 DefaultDataSharingAttributes getDefaultDSA()
const {
771 return isStackEmpty() ? DSA_unspecified : getTopOfStack().DefaultAttr;
774 return isStackEmpty() ?
SourceLocation() : getTopOfStack().DefaultAttrLoc;
778 return isStackEmpty()
780 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior;
783 getDefaultmapModifierAtLevel(
unsigned Level,
785 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior;
787 bool isDefaultmapCapturedByRef(
unsigned Level,
790 getDefaultmapModifierAtLevel(Level, Kind);
791 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) {
792 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) ||
793 (M == OMPC_DEFAULTMAP_MODIFIER_to) ||
794 (M == OMPC_DEFAULTMAP_MODIFIER_from) ||
795 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom);
802 case OMPC_DEFAULTMAP_scalar:
803 case OMPC_DEFAULTMAP_pointer:
805 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) ||
806 (M == OMPC_DEFAULTMAP_MODIFIER_default);
807 case OMPC_DEFAULTMAP_aggregate:
808 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate;
812 llvm_unreachable(
"Unexpected OpenMPDefaultmapClauseKind enum");
814 bool mustBeFirstprivateAtLevel(
unsigned Level,
817 getDefaultmapModifierAtLevel(Level, Kind);
818 return mustBeFirstprivateBase(M, Kind);
822 return mustBeFirstprivateBase(M, Kind);
826 bool isThreadPrivate(
VarDecl *D) {
827 const DSAVarData DVar = getTopDSA(D,
false);
832 void setOrderedRegion(
bool IsOrdered,
const Expr *Param,
835 getTopOfStack().OrderedRegion.emplace(Param, Clause);
837 getTopOfStack().OrderedRegion.reset();
841 bool isOrderedRegion()
const {
842 if (
const SharingMapTy *Top = getTopOfStackOrNull())
843 return Top->OrderedRegion.has_value();
847 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam()
const {
848 if (
const SharingMapTy *Top = getTopOfStackOrNull())
849 if (Top->OrderedRegion)
850 return Top->OrderedRegion.value();
851 return std::make_pair(
nullptr,
nullptr);
855 bool isParentOrderedRegion()
const {
856 if (
const SharingMapTy *
Parent = getSecondOnStackOrNull())
857 return Parent->OrderedRegion.has_value();
861 std::pair<const Expr *, OMPOrderedClause *>
862 getParentOrderedRegionParam()
const {
863 if (
const SharingMapTy *
Parent = getSecondOnStackOrNull())
864 if (
Parent->OrderedRegion)
865 return Parent->OrderedRegion.value();
866 return std::make_pair(
nullptr,
nullptr);
869 void setNowaitRegion(
bool IsNowait =
true) {
870 getTopOfStack().NowaitRegion = IsNowait;
874 bool isParentNowaitRegion()
const {
875 if (
const SharingMapTy *
Parent = getSecondOnStackOrNull())
876 return Parent->NowaitRegion;
880 void setUntiedRegion(
bool IsUntied =
true) {
881 getTopOfStack().UntiedRegion = IsUntied;
884 bool isUntiedRegion()
const {
885 const SharingMapTy *Top = getTopOfStackOrNull();
886 return Top ? Top->UntiedRegion :
false;
889 void setParentCancelRegion(
bool Cancel =
true) {
890 if (SharingMapTy *
Parent = getSecondOnStackOrNull())
891 Parent->CancelRegion |= Cancel;
894 bool isCancelRegion()
const {
895 const SharingMapTy *Top = getTopOfStackOrNull();
896 return Top ? Top->CancelRegion :
false;
901 if (SharingMapTy *
Parent = getSecondOnStackOrNull())
902 Parent->PrevScanLocation = Loc;
905 bool doesParentHasScanDirective()
const {
906 const SharingMapTy *Top = getSecondOnStackOrNull();
907 return Top ? Top->PrevScanLocation.isValid() :
false;
911 const SharingMapTy *Top = getSecondOnStackOrNull();
916 if (SharingMapTy *
Parent = getSecondOnStackOrNull())
917 Parent->PrevOrderedLocation = Loc;
920 bool doesParentHasOrderedDirective()
const {
921 const SharingMapTy *Top = getSecondOnStackOrNull();
922 return Top ? Top->PrevOrderedLocation.isValid() :
false;
926 const SharingMapTy *Top = getSecondOnStackOrNull();
931 void setAssociatedLoops(
unsigned Val) {
932 getTopOfStack().AssociatedLoops = Val;
934 getTopOfStack().HasMutipleLoops =
true;
937 unsigned getAssociatedLoops()
const {
938 const SharingMapTy *Top = getTopOfStackOrNull();
939 return Top ? Top->AssociatedLoops : 0;
942 bool hasMutipleLoops()
const {
943 const SharingMapTy *Top = getTopOfStackOrNull();
944 return Top ? Top->HasMutipleLoops :
false;
950 if (SharingMapTy *
Parent = getSecondOnStackOrNull())
951 Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
954 bool hasInnerTeamsRegion()
const {
955 return getInnerTeamsRegionLoc().
isValid();
959 const SharingMapTy *Top = getTopOfStackOrNull();
963 Scope *getCurScope()
const {
964 const SharingMapTy *Top = getTopOfStackOrNull();
965 return Top ? Top->CurScope :
nullptr;
967 void setContext(
DeclContext *DC) { getTopOfStack().Context = DC; }
969 const SharingMapTy *Top = getTopOfStackOrNull();
975 bool checkMappableExprComponentListsForDecl(
976 const ValueDecl *VD,
bool CurrentRegionOnly,
977 const llvm::function_ref<
989 if (CurrentRegionOnly)
994 for (; SI != SE; ++SI) {
995 auto MI = SI->MappedExprComponents.find(VD);
996 if (MI != SI->MappedExprComponents.end())
998 MI->second.Components)
999 if (Check(L, MI->second.Kind))
1007 bool checkMappableExprComponentListsForDeclAtLevel(
1009 const llvm::function_ref<
1013 if (getStackSize() <= Level)
1016 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1017 auto MI = StackElem.MappedExprComponents.find(VD);
1018 if (MI != StackElem.MappedExprComponents.end())
1020 MI->second.Components)
1021 if (Check(L, MI->second.Kind))
1028 void addMappableExpressionComponents(
1032 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
1034 MEC.Components.resize(MEC.Components.size() + 1);
1035 MEC.Components.back().append(Components.begin(), Components.end());
1036 MEC.Kind = WhereFoundClauseKind;
1039 unsigned getNestingLevel()
const {
1040 assert(!isStackEmpty());
1041 return getStackSize() - 1;
1044 const OperatorOffsetTy &OpsOffs) {
1045 SharingMapTy *
Parent = getSecondOnStackOrNull();
1047 Parent->DoacrossDepends.try_emplace(
C, OpsOffs);
1049 llvm::iterator_range<DoacrossDependMapTy::const_iterator>
1050 getDoacrossDependClauses()
const {
1051 const SharingMapTy &StackElem = getTopOfStack();
1053 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
1054 return llvm::make_range(Ref.begin(), Ref.end());
1056 return llvm::make_range(StackElem.DoacrossDepends.end(),
1057 StackElem.DoacrossDepends.end());
1061 void addMappedClassesQualTypes(
QualType QT) {
1062 SharingMapTy &StackElem = getTopOfStack();
1063 StackElem.MappedClassesQualTypes.insert(QT);
1067 bool isClassPreviouslyMapped(
QualType QT)
const {
1068 const SharingMapTy &StackElem = getTopOfStack();
1069 return StackElem.MappedClassesQualTypes.contains(QT);
1073 void addToParentTargetRegionLinkGlobals(
DeclRefExpr *E) {
1074 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
1075 E->
getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
1076 "Expected declare target link global.");
1077 for (
auto &Elem : *
this) {
1079 Elem.DeclareTargetLinkVarDecls.push_back(E);
1089 "Expected target executable directive.");
1090 return getTopOfStack().DeclareTargetLinkVarDecls;
1094 void addInnerAllocatorExpr(
Expr *E) {
1095 getTopOfStack().InnerUsedAllocators.push_back(E);
1099 return getTopOfStack().InnerUsedAllocators;
1103 void addImplicitTaskFirstprivate(
unsigned Level,
Decl *D) {
1104 getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D);
1107 bool isImplicitTaskFirstprivate(
Decl *D)
const {
1108 return getTopOfStack().ImplicitTaskFirstprivates.contains(D);
1112 void addUsesAllocatorsDecl(
const Decl *D, UsesAllocatorsDeclKind Kind) {
1113 getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind);
1118 const Decl *D)
const {
1119 const SharingMapTy &StackElem = getTopOfStack();
1120 auto I = StackElem.UsesAllocatorsDecls.find(D);
1121 if (I == StackElem.UsesAllocatorsDecls.end())
1123 return I->getSecond();
1126 const SharingMapTy &StackElem = getTopOfStack();
1127 auto I = StackElem.UsesAllocatorsDecls.find(D);
1128 if (I == StackElem.UsesAllocatorsDecls.end())
1130 return I->getSecond();
1133 void addDeclareMapperVarRef(
Expr *Ref) {
1134 SharingMapTy &StackElem = getTopOfStack();
1135 StackElem.DeclareMapperVar = Ref;
1137 const Expr *getDeclareMapperVarRef()
const {
1138 const SharingMapTy *Top = getTopOfStackOrNull();
1139 return Top ? Top->DeclareMapperVar :
nullptr;
1143 const_iterator I = begin();
1144 const_iterator EndI = end();
1145 size_t StackLevel = getStackSize();
1146 for (; I != EndI; ++I) {
1147 if (I->DefaultAttr == DSA_firstprivate || I->DefaultAttr == DSA_private)
1151 assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI));
1154 for (
const auto &IFD : I->ImplicitDefaultFirstprivateFDs)
1155 if (IFD.FD == FD && IFD.StackLevel == StackLevel)
1160 bool isImplicitDefaultFirstprivateFD(
VarDecl *VD)
const {
1161 const_iterator I = begin();
1162 const_iterator EndI = end();
1163 for (; I != EndI; ++I)
1164 if (I->DefaultAttr == DSA_firstprivate || I->DefaultAttr == DSA_private)
1168 for (
const auto &IFD : I->ImplicitDefaultFirstprivateFDs)
1175 iterator I = begin();
1176 const_iterator EndI = end();
1177 size_t StackLevel = getStackSize();
1178 for (; I != EndI; ++I) {
1179 if (I->DefaultAttr == DSA_private || I->DefaultAttr == DSA_firstprivate) {
1180 I->ImplicitDefaultFirstprivateFDs.emplace_back(FD, StackLevel, VD);
1185 assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI));
1195 DKind == OMPD_unknown;
1201 if (
const auto *FE = dyn_cast<FullExpr>(E))
1202 E = FE->getSubExpr();
1204 if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
1205 E = MTE->getSubExpr();
1207 while (
const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
1208 E = Binder->getSubExpr();
1210 if (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
1211 E = ICE->getSubExprAsWritten();
1220 if (
const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
1221 if (
const auto *ME = dyn_cast<MemberExpr>(
getExprAsWritten(CED->getInit())))
1222 D = ME->getMemberDecl();
1223 const auto *VD = dyn_cast<VarDecl>(D);
1224 const auto *FD = dyn_cast<FieldDecl>(D);
1225 if (VD !=
nullptr) {
1241DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
1244 auto *VD = dyn_cast<VarDecl>(D);
1245 const auto *FD = dyn_cast<FieldDecl>(D);
1247 if (Iter == end()) {
1254 DVar.CKind = OMPC_shared;
1261 DVar.CKind = OMPC_shared;
1265 DVar.CKind = OMPC_shared;
1276 DVar.CKind = OMPC_private;
1280 DVar.DKind = Iter->Directive;
1283 if (Iter->SharingMap.count(D)) {
1284 const DSAInfo &Data = Iter->SharingMap.lookup(D);
1285 DVar.RefExpr = Data.RefExpr.getPointer();
1286 DVar.PrivateCopy = Data.PrivateCopy;
1287 DVar.CKind = Data.Attributes;
1288 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1289 DVar.Modifier = Data.Modifier;
1290 DVar.AppliedToPointee = Data.AppliedToPointee;
1298 switch (Iter->DefaultAttr) {
1300 DVar.CKind = OMPC_shared;
1301 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1305 case DSA_firstprivate:
1308 DVar.CKind = OMPC_unknown;
1310 DVar.CKind = OMPC_firstprivate;
1312 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1320 DVar.CKind = OMPC_unknown;
1322 DVar.CKind = OMPC_private;
1324 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1326 case DSA_unspecified:
1331 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1335 DVar.CKind = OMPC_shared;
1345 DSAVarData DVarTemp;
1346 const_iterator I = Iter, E = end();
1354 DVarTemp = getDSA(I, D);
1355 if (DVarTemp.CKind != OMPC_shared) {
1356 DVar.RefExpr =
nullptr;
1357 DVar.CKind = OMPC_firstprivate;
1360 }
while (I != E && !isImplicitTaskingRegion(I->Directive));
1362 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
1371 return getDSA(++Iter, D);
1375 const Expr *NewDE) {
1376 assert(!isStackEmpty() &&
"Data sharing attributes stack is empty");
1378 SharingMapTy &StackElem = getTopOfStack();
1379 auto It = StackElem.AlignedMap.find(D);
1380 if (It == StackElem.AlignedMap.end()) {
1381 assert(NewDE &&
"Unexpected nullptr expr to be added into aligned map");
1382 StackElem.AlignedMap[D] = NewDE;
1385 assert(It->second &&
"Unexpected nullptr expr in the aligned map");
1389const Expr *DSAStackTy::addUniqueNontemporal(
const ValueDecl *D,
1390 const Expr *NewDE) {
1391 assert(!isStackEmpty() &&
"Data sharing attributes stack is empty");
1393 SharingMapTy &StackElem = getTopOfStack();
1394 auto It = StackElem.NontemporalMap.find(D);
1395 if (It == StackElem.NontemporalMap.end()) {
1396 assert(NewDE &&
"Unexpected nullptr expr to be added into aligned map");
1397 StackElem.NontemporalMap[D] = NewDE;
1400 assert(It->second &&
"Unexpected nullptr expr in the aligned map");
1405 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1407 SharingMapTy &StackElem = getTopOfStack();
1408 StackElem.LCVMap.try_emplace(
1409 D, LCDeclInfo(StackElem.LCVMap.size() + 1,
Capture));
1412const DSAStackTy::LCDeclInfo
1413DSAStackTy::isLoopControlVariable(
const ValueDecl *D)
const {
1414 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1416 const SharingMapTy &StackElem = getTopOfStack();
1417 auto It = StackElem.LCVMap.find(D);
1418 if (It != StackElem.LCVMap.end())
1420 return {0,
nullptr};
1423const DSAStackTy::LCDeclInfo
1424DSAStackTy::isLoopControlVariable(
const ValueDecl *D,
unsigned Level)
const {
1425 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1427 for (
unsigned I = Level + 1; I > 0; --I) {
1428 const SharingMapTy &StackElem = getStackElemAtLevel(I - 1);
1429 auto It = StackElem.LCVMap.find(D);
1430 if (It != StackElem.LCVMap.end())
1433 return {0,
nullptr};
1436const DSAStackTy::LCDeclInfo
1437DSAStackTy::isParentLoopControlVariable(
const ValueDecl *D)
const {
1438 const SharingMapTy *
Parent = getSecondOnStackOrNull();
1439 assert(
Parent &&
"Data-sharing attributes stack is empty");
1441 auto It =
Parent->LCVMap.find(D);
1442 if (It !=
Parent->LCVMap.end())
1444 return {0,
nullptr};
1447const ValueDecl *DSAStackTy::getParentLoopControlVariable(
unsigned I)
const {
1448 const SharingMapTy *
Parent = getSecondOnStackOrNull();
1449 assert(
Parent &&
"Data-sharing attributes stack is empty");
1450 if (
Parent->LCVMap.size() < I)
1452 for (
const auto &Pair :
Parent->LCVMap)
1453 if (Pair.second.first == I)
1460 bool AppliedToPointee) {
1462 if (A == OMPC_threadprivate) {
1463 DSAInfo &Data = Threadprivates[D];
1464 Data.Attributes = A;
1465 Data.RefExpr.setPointer(E);
1466 Data.PrivateCopy =
nullptr;
1467 Data.Modifier = Modifier;
1469 DSAInfo &Data = getTopOfStack().SharingMap[D];
1470 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
1471 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
1472 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
1473 (isLoopControlVariable(D).first && A == OMPC_private));
1474 Data.Modifier = Modifier;
1475 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
1476 Data.RefExpr.setInt(
true);
1479 const bool IsLastprivate =
1480 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
1481 Data.Attributes = A;
1482 Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1483 Data.PrivateCopy = PrivateCopy;
1484 Data.AppliedToPointee = AppliedToPointee;
1486 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->
getDecl()];
1487 Data.Modifier = Modifier;
1488 Data.Attributes = A;
1489 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1490 Data.PrivateCopy =
nullptr;
1491 Data.AppliedToPointee = AppliedToPointee;
1498 StringRef Name,
const AttrVec *Attrs =
nullptr,
1513 OMPReferencedVarAttr::CreateImplicit(SemaRef.
Context, OrigRef));
1520 bool RefersToCapture =
false) {
1531 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1533 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1534 "Additional reduction info may be specified only for reduction items.");
1535 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1536 assert(ReductionData.ReductionRange.isInvalid() &&
1537 (getTopOfStack().
Directive == OMPD_taskgroup ||
1541 "Additional reduction info may be specified only once for reduction "
1543 ReductionData.set(BOK, SR);
1544 Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1545 if (!TaskgroupReductionRef) {
1548 TaskgroupReductionRef =
1554 const Expr *ReductionRef) {
1556 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1558 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1559 "Additional reduction info may be specified only for reduction items.");
1560 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1561 assert(ReductionData.ReductionRange.isInvalid() &&
1562 (getTopOfStack().
Directive == OMPD_taskgroup ||
1566 "Additional reduction info may be specified only once for reduction "
1568 ReductionData.set(ReductionRef, SR);
1569 Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1570 if (!TaskgroupReductionRef) {
1573 TaskgroupReductionRef =
1578const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1580 Expr *&TaskgroupDescriptor)
const {
1582 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty.");
1583 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1584 const DSAInfo &Data = I->SharingMap.lookup(D);
1585 if (Data.Attributes != OMPC_reduction ||
1586 Data.Modifier != OMPC_REDUCTION_task)
1588 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1589 if (!ReductionData.ReductionOp ||
1590 ReductionData.ReductionOp.is<
const Expr *>())
1591 return DSAVarData();
1592 SR = ReductionData.ReductionRange;
1593 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1594 assert(I->TaskgroupReductionRef &&
"taskgroup reduction reference "
1595 "expression for the descriptor is not "
1597 TaskgroupDescriptor = I->TaskgroupReductionRef;
1598 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1599 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1602 return DSAVarData();
1605const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1607 Expr *&TaskgroupDescriptor)
const {
1609 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty.");
1610 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1611 const DSAInfo &Data = I->SharingMap.lookup(D);
1612 if (Data.Attributes != OMPC_reduction ||
1613 Data.Modifier != OMPC_REDUCTION_task)
1615 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1616 if (!ReductionData.ReductionOp ||
1617 !ReductionData.ReductionOp.is<
const Expr *>())
1618 return DSAVarData();
1619 SR = ReductionData.ReductionRange;
1620 ReductionRef = ReductionData.ReductionOp.get<
const Expr *>();
1621 assert(I->TaskgroupReductionRef &&
"taskgroup reduction reference "
1622 "expression for the descriptor is not "
1624 TaskgroupDescriptor = I->TaskgroupReductionRef;
1625 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1626 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1629 return DSAVarData();
1632bool DSAStackTy::isOpenMPLocal(
VarDecl *D, const_iterator I)
const {
1634 for (const_iterator E = end(); I != E; ++I) {
1635 if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1638 Scope *TopScope = I->CurScope->getParent();
1639 Scope *CurScope = getCurScope();
1640 while (CurScope && CurScope != TopScope && !CurScope->
isDeclScope(D))
1642 return CurScope != TopScope;
1645 if (I->Context == DC)
1654 bool AcceptIfMutable =
true,
1655 bool *IsClassType =
nullptr) {
1657 Type =
Type.getNonReferenceType().getCanonicalType();
1658 bool IsConstant =
Type.isConstant(Context);
1663 if (
const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1665 RD = CTD->getTemplatedDecl();
1675 bool AcceptIfMutable =
true,
1676 bool ListItemNotVar =
false) {
1680 unsigned Diag = ListItemNotVar ? diag::err_omp_const_list_item
1681 : IsClassType ? diag::err_omp_const_not_mutable_variable
1682 : diag::err_omp_const_variable;
1683 SemaRef.
Diag(ELoc,
Diag) << getOpenMPClauseName(CKind);
1684 if (!ListItemNotVar && D) {
1685 const VarDecl *VD = dyn_cast<VarDecl>(D);
1689 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1697const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(
ValueDecl *D,
1702 auto *VD = dyn_cast<VarDecl>(D);
1703 auto TI = Threadprivates.find(D);
1704 if (TI != Threadprivates.end()) {
1705 DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1706 DVar.CKind = OMPC_threadprivate;
1707 DVar.Modifier = TI->getSecond().Modifier;
1710 if (VD && VD->
hasAttr<OMPThreadPrivateDeclAttr>()) {
1713 VD->
getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1714 DVar.CKind = OMPC_threadprivate;
1715 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1722 !(VD->
hasAttr<OMPThreadPrivateDeclAttr>() &&
1729 DVar.CKind = OMPC_threadprivate;
1730 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1735 !isLoopControlVariable(D).first) {
1736 const_iterator IterTarget =
1737 std::find_if(begin(), end(), [](
const SharingMapTy &Data) {
1740 if (IterTarget != end()) {
1741 const_iterator ParentIterTarget = IterTarget + 1;
1742 for (const_iterator Iter = begin(); Iter != ParentIterTarget; ++Iter) {
1743 if (isOpenMPLocal(VD, Iter)) {
1747 DVar.CKind = OMPC_threadprivate;
1751 if (!isClauseParsingMode() || IterTarget != begin()) {
1752 auto DSAIter = IterTarget->SharingMap.find(D);
1753 if (DSAIter != IterTarget->SharingMap.end() &&
1755 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1756 DVar.CKind = OMPC_threadprivate;
1759 const_iterator End = end();
1761 std::distance(ParentIterTarget, End),
1765 IterTarget->ConstructLoc);
1766 DVar.CKind = OMPC_threadprivate;
1786 const_iterator I = begin();
1787 const_iterator EndI = end();
1788 if (FromParent && I != EndI)
1791 auto It = I->SharingMap.find(D);
1792 if (It != I->SharingMap.end()) {
1793 const DSAInfo &Data = It->getSecond();
1794 DVar.RefExpr = Data.RefExpr.getPointer();
1795 DVar.PrivateCopy = Data.PrivateCopy;
1796 DVar.CKind = Data.Attributes;
1797 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1798 DVar.DKind = I->Directive;
1799 DVar.Modifier = Data.Modifier;
1800 DVar.AppliedToPointee = Data.AppliedToPointee;
1805 DVar.CKind = OMPC_shared;
1812 if (SemaRef.
LangOpts.OpenMP <= 31) {
1820 DSAVarData DVarTemp = hasInnermostDSA(
1823 return C == OMPC_firstprivate ||
C == OMPC_shared;
1825 MatchesAlways, FromParent);
1826 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1829 DVar.CKind = OMPC_shared;
1836 const_iterator I = begin();
1837 const_iterator EndI = end();
1838 if (FromParent && I != EndI)
1842 auto It = I->SharingMap.find(D);
1843 if (It != I->SharingMap.end()) {
1844 const DSAInfo &Data = It->getSecond();
1845 DVar.RefExpr = Data.RefExpr.getPointer();
1846 DVar.PrivateCopy = Data.PrivateCopy;
1847 DVar.CKind = Data.Attributes;
1848 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1849 DVar.DKind = I->Directive;
1850 DVar.Modifier = Data.Modifier;
1851 DVar.AppliedToPointee = Data.AppliedToPointee;
1857const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(
ValueDecl *D,
1858 bool FromParent)
const {
1859 if (isStackEmpty()) {
1861 return getDSA(I, D);
1864 const_iterator StartI = begin();
1865 const_iterator EndI = end();
1866 if (FromParent && StartI != EndI)
1868 return getDSA(StartI, D);
1871const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(
ValueDecl *D,
1872 unsigned Level)
const {
1873 if (getStackSize() <= Level)
1874 return DSAVarData();
1876 const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level);
1877 return getDSA(StartI, D);
1880const DSAStackTy::DSAVarData
1883 DefaultDataSharingAttributes)>
1886 bool FromParent)
const {
1890 const_iterator I = begin();
1891 const_iterator EndI = end();
1892 if (FromParent && I != EndI)
1894 for (; I != EndI; ++I) {
1895 if (!DPred(I->Directive) &&
1896 !isImplicitOrExplicitTaskingRegion(I->Directive))
1898 const_iterator NewI = I;
1899 DSAVarData DVar = getDSA(NewI, D);
1900 if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee, I->DefaultAttr))
1906const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1909 bool FromParent)
const {
1913 const_iterator StartI = begin();
1914 const_iterator EndI = end();
1915 if (FromParent && StartI != EndI)
1917 if (StartI == EndI || !DPred(StartI->Directive))
1919 const_iterator NewI = StartI;
1920 DSAVarData DVar = getDSA(NewI, D);
1921 return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee))
1926bool DSAStackTy::hasExplicitDSA(
1929 unsigned Level,
bool NotLastprivate)
const {
1930 if (getStackSize() <= Level)
1933 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1934 auto I = StackElem.SharingMap.find(D);
1935 if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() &&
1936 CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) &&
1937 (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1940 auto LI = StackElem.LCVMap.find(D);
1941 if (LI != StackElem.LCVMap.end())
1942 return CPred(OMPC_private,
false);
1946bool DSAStackTy::hasExplicitDirective(
1948 unsigned Level)
const {
1949 if (getStackSize() <= Level)
1951 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1952 return DPred(StackElem.Directive);
1955bool DSAStackTy::hasDirective(
1959 bool FromParent)
const {
1961 size_t Skip = FromParent ? 2 : 1;
1962 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end();
1964 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1970void Sema::InitDataSharingAttributesStack() {
1971 VarDataSharingAttributesStack =
new DSAStackTy(*
this);
1974#define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1976void Sema::pushOpenMPFunctionRegion() {
DSAStack->pushFunction(); }
1984 "Expected OpenMP device compilation.");
1990enum class FunctionEmissionStatus {
2000 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
2001 "Expected OpenMP device compilation.");
2007 case FunctionEmissionStatus::Emitted:
2008 Kind = SemaDiagnosticBuilder::K_Immediate;
2010 case FunctionEmissionStatus::Unknown:
2019 ? SemaDiagnosticBuilder::K_Deferred
2020 : SemaDiagnosticBuilder::K_Immediate;
2022 case FunctionEmissionStatus::TemplateDiscarded:
2023 case FunctionEmissionStatus::OMPDiscarded:
2024 Kind = SemaDiagnosticBuilder::K_Nop;
2026 case FunctionEmissionStatus::CUDADiscarded:
2027 llvm_unreachable(
"CUDADiscarded unexpected in OpenMP device compilation");
2038 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice &&
2039 "Expected OpenMP host compilation.");
2045 case FunctionEmissionStatus::Emitted:
2046 Kind = SemaDiagnosticBuilder::K_Immediate;
2048 case FunctionEmissionStatus::Unknown:
2049 Kind = SemaDiagnosticBuilder::K_Deferred;
2051 case FunctionEmissionStatus::TemplateDiscarded:
2052 case FunctionEmissionStatus::OMPDiscarded:
2053 case FunctionEmissionStatus::CUDADiscarded:
2054 Kind = SemaDiagnosticBuilder::K_Nop;
2064 if (LO.OpenMP <= 45) {
2066 return OMPC_DEFAULTMAP_scalar;
2067 return OMPC_DEFAULTMAP_aggregate;
2070 return OMPC_DEFAULTMAP_pointer;
2072 return OMPC_DEFAULTMAP_scalar;
2073 return OMPC_DEFAULTMAP_aggregate;
2077 unsigned OpenMPCaptureLevel)
const {
2078 assert(LangOpts.OpenMP &&
"OpenMP is not allowed");
2081 bool IsByRef =
true;
2087 bool IsVariableUsedInMapClause =
false;
2149 bool IsVariableAssociatedWithSection =
false;
2151 DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2153 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection,
2160 if (WhereFoundClauseKind != OMPC_map)
2163 auto EI = MapExprComponents.rbegin();
2164 auto EE = MapExprComponents.rend();
2166 assert(EI != EE &&
"Invalid map expression!");
2168 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
2169 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
2175 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
2176 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
2177 isa<MemberExpr>(EI->getAssociatedExpression()) ||
2178 isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) {
2179 IsVariableAssociatedWithSection =
true;
2188 if (IsVariableUsedInMapClause) {
2191 IsByRef = !(Ty->
isPointerType() && IsVariableAssociatedWithSection);
2196 IsByRef = (
DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
2199 DSAStack->isDefaultmapCapturedByRef(
2204 return K == OMPC_reduction && !AppliedToPointee;
2212 ((IsVariableUsedInMapClause &&
2213 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) ==
2218 return K == OMPC_firstprivate ||
2219 (K == OMPC_reduction && AppliedToPointee);
2222 DSAStack->isUsesAllocatorsDecl(Level, D))) &&
2226 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) &&
2229 !((
DSAStack->getDefaultDSA() == DSA_firstprivate ||
2230 DSAStack->getDefaultDSA() == DSA_private) &&
2234 !
DSAStack->isLoopControlVariable(D, Level).first);
2251unsigned Sema::getOpenMPNestingLevel()
const {
2252 assert(getLangOpts().OpenMP);
2253 return DSAStack->getNestingLevel();
2263 !
DSAStack->isClauseParsingMode()) ||
2274 if (!dyn_cast<FieldDecl>(D))
2276 DSAStackTy::DSAVarData DVarPrivate =
DSAStack->hasDSA(
2279 DefaultDataSharingAttributes DefaultAttr) {
2281 (DefaultAttr == DSA_firstprivate || DefaultAttr == DSA_private);
2285 if (DVarPrivate.CKind != OMPC_unknown)
2291 Expr *CaptureExpr,
bool WithInit,
2297 assert(LangOpts.OpenMP &&
"OpenMP is not allowed");
2300 auto *VD = dyn_cast<VarDecl>(D);
2309 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
2316 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
2317 if (isInOpenMPTargetExecutionDirective()) {
2318 DSAStackTy::DSAVarData DVarTop =
2320 if (DVarTop.CKind != OMPC_unknown && DVarTop.RefExpr)
2325 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2329 llvm::reverse(FunctionScopes),
2330 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) {
2331 if (!isa<CapturingScopeInfo>(FSI))
2333 if (
auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2339 assert(CSI &&
"Failed to find CapturedRegionScopeInfo");
2346 if (isInOpenMPDeclareTargetContext()) {
2349 if (LangOpts.OpenMP <= 45 &&
2350 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2351 checkDeclIsAllowedInOpenMPTarget(
nullptr, VD);
2356 if (CheckScopeInfo) {
2357 bool OpenMPFound =
false;
2358 for (
unsigned I = StopAt + 1; I > 0; --I) {
2360 if (!isa<CapturingScopeInfo>(FSI))
2362 if (
auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2372 if (
DSAStack->getCurrentDirective() != OMPD_unknown &&
2373 (!
DSAStack->isClauseParsingMode() ||
2374 DSAStack->getParentDirective() != OMPD_unknown)) {
2375 auto &&Info =
DSAStack->isLoopControlVariable(D);
2378 isImplicitOrExplicitTaskingRegion(
DSAStack->getCurrentDirective())) ||
2379 (VD &&
DSAStack->isForceVarCapturing()))
2380 return VD ? VD : Info.second;
2381 DSAStackTy::DSAVarData DVarTop =
2383 if (DVarTop.CKind != OMPC_unknown &&
isOpenMPPrivate(DVarTop.CKind) &&
2391 DSAStackTy::DSAVarData DVarPrivate =
DSAStack->hasDSA(
2399 if (VD && !VD->
hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
2400 ((
DSAStack->getDefaultDSA() != DSA_none &&
2401 DSAStack->getDefaultDSA() != DSA_private &&
2402 DSAStack->getDefaultDSA() != DSA_firstprivate) ||
2403 DVarTop.CKind == OMPC_shared))
2405 auto *FD = dyn_cast<FieldDecl>(D);
2406 if (DVarPrivate.CKind != OMPC_unknown && !VD && FD &&
2407 !DVarPrivate.PrivateCopy) {
2408 DSAStackTy::DSAVarData DVarPrivate =
DSAStack->hasDSA(
2411 DefaultDataSharingAttributes DefaultAttr) {
2413 (DefaultAttr == DSA_firstprivate ||
2414 DefaultAttr == DSA_private);
2418 if (DVarPrivate.CKind == OMPC_unknown)
2424 if (getCurrentThisType().isNull())
2436 *
this, FD->
getIdentifier(), ME, DVarPrivate.CKind != OMPC_private,
2437 CurContext->getParent(),
false);
2441 DSAStack->addImplicitDefaultFirstprivateFD(FD, VD);
2444 if (DVarPrivate.CKind != OMPC_unknown ||
2445 (VD && (
DSAStack->getDefaultDSA() == DSA_none ||
2446 DSAStack->getDefaultDSA() == DSA_private ||
2447 DSAStack->getDefaultDSA() == DSA_firstprivate)))
2453void Sema::adjustOpenMPTargetScopeIndex(
unsigned &FunctionScopesIndex,
2454 unsigned Level)
const {
2455 FunctionScopesIndex -= getOpenMPCaptureLevels(
DSAStack->getDirective(Level));
2459 assert(LangOpts.OpenMP &&
"OpenMP must be enabled.");
2465 assert(LangOpts.OpenMP &&
"OpenMP must be enabled.");
2467 DSAStack->resetPossibleLoopCounter();
2473 unsigned CapLevel)
const {
2474 assert(LangOpts.OpenMP &&
"OpenMP is not allowed");
2475 if (
DSAStack->getCurrentDirective() != OMPD_unknown &&
2476 (!
DSAStack->isClauseParsingMode() ||
2477 DSAStack->getParentDirective() != OMPD_unknown)) {
2478 DSAStackTy::DSAVarData DVarPrivate =
DSAStack->hasDSA(
2481 DefaultDataSharingAttributes DefaultAttr) {
2483 DefaultAttr == DSA_private;
2487 if (DVarPrivate.CKind == OMPC_private && isa<OMPCapturedExprDecl>(D) &&
2488 DSAStack->isImplicitDefaultFirstprivateFD(cast<VarDecl>(D)) &&
2489 !
DSAStack->isLoopControlVariable(D).first)
2490 return OMPC_private;
2493 bool IsTriviallyCopyable =
2503 (IsTriviallyCopyable ||
2509 return OMPC_firstprivate;
2510 DSAStackTy::DSAVarData DVar =
DSAStack->getImplicitDSA(D, Level);
2511 if (DVar.CKind != OMPC_shared &&
2512 !
DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) {
2513 DSAStack->addImplicitTaskFirstprivate(Level, D);
2514 return OMPC_firstprivate;
2520 DSAStack->resetPossibleLoopCounter(D);
2522 return OMPC_private;
2525 DSAStack->isLoopControlVariable(D).first) &&
2530 return OMPC_private;
2532 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
2538 return OMPC_private;
2543 DSAStack->isUsesAllocatorsDecl(Level, D).value_or(
2544 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
2545 DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
2546 return OMPC_private;
2550 (
DSAStack->isClauseParsingMode() &&
2551 DSAStack->getClauseParsingMode() == OMPC_private) ||
2556 return K == OMPD_taskgroup ||
2557 ((isOpenMPParallelDirective(K) ||
2558 isOpenMPWorksharingDirective(K)) &&
2559 !isOpenMPSimdDirective(K));
2562 DSAStack->isTaskgroupReductionRef(D, Level)))
2569 assert(LangOpts.OpenMP &&
"OpenMP is not allowed");
2572 for (
unsigned I =
DSAStack->getNestingLevel() + 1; I > Level; --I) {
2573 const unsigned NewLevel = I - 1;
2577 if (isOpenMPPrivate(K) && !AppliedToPointee) {
2585 if (
DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2595 if (
DSAStack->mustBeFirstprivateAtLevel(
2597 OMPC = OMPC_firstprivate;
2601 if (OMPC != OMPC_unknown)
2602 FD->
addAttr(OMPCaptureKindAttr::CreateImplicit(Context,
unsigned(OMPC)));
2606 unsigned CaptureLevel)
const {
2607 assert(LangOpts.OpenMP &&
"OpenMP is not allowed");
2612 const auto *VD = dyn_cast<VarDecl>(D);
2616 Regions[CaptureLevel] != OMPD_task;
2620 unsigned CaptureLevel)
const {
2621 assert(LangOpts.OpenMP &&
"OpenMP is not allowed");
2624 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
2626 if (isInOpenMPTargetExecutionDirective())
2628 DSAStackTy::DSAVarData TopDVar =
2630 unsigned NumLevels =
2631 getOpenMPCaptureLevels(
DSAStack->getDirective(Level));
2635 return (NumLevels == CaptureLevel + 1 &&
2636 (TopDVar.CKind != OMPC_shared ||
2637 DSAStack->getDefaultDSA() == DSA_firstprivate));
2640 DSAStackTy::DSAVarData DVar =
DSAStack->getImplicitDSA(D, Level);
2641 if (DVar.CKind != OMPC_shared)
2643 }
while (Level > 0);
2649void Sema::DestroyDataSharingAttributesStack() {
delete DSAStack; }
2653 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
2657 assert(isInOpenMPDeclareVariantScope() &&
2658 "Not in OpenMP declare variant scope!");
2660 OMPDeclareVariantScopes.pop_back();
2666 assert(LangOpts.OpenMP &&
"Expected OpenMP compilation mode.");
2670 if (LangOpts.OpenMPIsDevice &&
2671 (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host))
2674 if (!LangOpts.OpenMPIsDevice && DevTy &&
2675 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2678 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD);
2679 if (LangOpts.OpenMPIsDevice && DevTy &&
2680 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2682 StringRef HostDevTy =
2684 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
2685 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2686 diag::note_omp_marked_device_type_here)
2690 if (!LangOpts.OpenMPIsDevice && !LangOpts.OpenMPOffloadMandatory && DevTy &&
2691 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2694 OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2695 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
2696 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2697 diag::note_omp_marked_device_type_here)
2705 DSAStack->push(DKind, DirName, CurScope, Loc);
2706 PushExpressionEvaluationContext(
2707 ExpressionEvaluationContext::PotentiallyEvaluated);
2715 DSAStack->setClauseParsingMode(OMPC_unknown);
2716 CleanupVarDeclMarking();
2719static std::pair<ValueDecl *, bool>
2721 SourceRange &ERange,
bool AllowArraySection =
false);
2726 bool InscanFound =
false;
2733 if (
C->getClauseKind() != OMPC_reduction)
2736 if (RC->getModifier() == OMPC_REDUCTION_inscan) {
2738 InscanLoc = RC->getModifierLoc();
2741 if (RC->getModifier() == OMPC_REDUCTION_task) {
2751 S.
Diag(RC->getModifierLoc(),
2752 diag::err_omp_reduction_task_not_parallel_or_worksharing);
2758 if (
C->getClauseKind() != OMPC_reduction)
2761 if (RC->getModifier() != OMPC_REDUCTION_inscan) {
2764 : RC->getModifierLoc(),
2765 diag::err_omp_inscan_reduction_expected);
2766 S.
Diag(InscanLoc, diag::note_omp_previous_inscan_reduction);
2769 for (
Expr *Ref : RC->varlists()) {
2770 assert(Ref &&
"NULL expr in OpenMP nontemporal clause.");
2773 Expr *SimpleRefExpr = Ref;
2780 S.
Diag(Ref->getExprLoc(),
2781 diag::err_omp_reduction_not_inclusive_exclusive)
2782 << Ref->getSourceRange();
2796 const DSAStackTy::DSAVarData &DVar,
2797 bool IsLoopIterVar =
false);
2805 if (
const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2807 if (
auto *Clause = dyn_cast<OMPLastprivateClause>(
C)) {
2809 for (
Expr *DE : Clause->varlists()) {
2810 if (DE->isValueDependent() || DE->isTypeDependent()) {
2811 PrivateCopies.push_back(
nullptr);
2817 const DSAStackTy::DSAVarData DVar =
2819 if (DVar.CKind == OMPC_lastprivate) {
2826 *
this, DE->getExprLoc(),
Type.getUnqualifiedType(),
2828 ActOnUninitializedDecl(VDPrivate);
2830 PrivateCopies.push_back(
nullptr);
2834 *
this, VDPrivate, DE->
getType(), DE->getExprLoc()));
2838 PrivateCopies.push_back(
nullptr);
2841 Clause->setPrivateCopies(PrivateCopies);
2845 if (
auto *Clause = dyn_cast<OMPNontemporalClause>(
C)) {
2847 for (
Expr *RefExpr : Clause->varlists()) {
2848 assert(RefExpr &&
"NULL expr in OpenMP nontemporal clause.");
2851 Expr *SimpleRefExpr = RefExpr;
2855 PrivateRefs.push_back(RefExpr);
2860 const DSAStackTy::DSAVarData DVar =
2862 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2865 Clause->setPrivateRefs(PrivateRefs);
2868 if (
auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(
C)) {
2869 for (
unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) {
2875 if (!VD || !isa<VarDecl>(VD))
2877 DSAStackTy::DSAVarData DVar =
2883 Expr *MapExpr =
nullptr;
2885 DSAStack->checkMappableExprComponentListsForDecl(
2891 auto MI = MapExprComponents.rbegin();
2892 auto ME = MapExprComponents.rend();
2894 MI->getAssociatedDeclaration()->getCanonicalDecl() ==
2895 VD->getCanonicalDecl()) {
2896 MapExpr = MI->getAssociatedExpression();
2901 Diag(D.Allocator->getExprLoc(),
2902 diag::err_omp_allocator_used_in_clauses)
2907 Diag(MapExpr->getExprLoc(), diag::note_used_here)
2908 << MapExpr->getSourceRange();
2915 if (!CurContext->isDependentContext())
2921 DiscardCleanupsInEvaluationContext();
2922 PopExpressionEvaluationContext();
2926 Expr *NumIterations,
Sema &SemaRef,
2927 Scope *S, DSAStackTy *Stack);
2936 explicit VarDeclFilterCCC(
Sema &S) : SemaRef(S) {}
2937 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
2939 if (
const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
2947 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
2948 return std::make_unique<VarDeclFilterCCC>(*
this);
2957 explicit VarOrFuncDeclFilterCCC(
Sema &S) : SemaRef(S) {}
2958 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
2960 if (ND && ((isa<VarDecl>(ND) && ND->
getKind() == Decl::Var) ||
2961 isa<FunctionDecl>(ND))) {
2968 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
2969 return std::make_unique<VarOrFuncDeclFilterCCC>(*
this);
2980 LookupParsedName(Lookup, CurScope, &ScopeSpec,
true);
2987 VarDeclFilterCCC CCC(*
this);
2989 CorrectTypo(
Id, LookupOrdinaryName, CurScope,
nullptr, CCC,
2990 CTK_ErrorRecovery)) {
2991 diagnoseTypo(Corrected,
2992 PDiag(Lookup.
empty()
2993 ? diag::err_undeclared_var_use_suggest
2994 : diag::err_omp_expected_var_arg_suggest)
2996 VD = Corrected.getCorrectionDeclAs<
VarDecl>();
2998 Diag(
Id.getLoc(), Lookup.
empty() ? diag::err_undeclared_var_use
2999 : diag::err_omp_expected_var_arg)
3004 Diag(
Id.getLoc(), diag::err_omp_expected_var_arg) <<
Id.getName();
3013 Diag(
Id.getLoc(), diag::err_omp_global_var_arg)
3018 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3029 !getCurLexicalContext()->isTranslationUnit()) {
3030 Diag(
Id.getLoc(), diag::err_omp_var_scope)
3031 << getOpenMPDirectiveName(Kind) << VD;
3035 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3045 Diag(
Id.getLoc(), diag::err_omp_var_scope)
3046 << getOpenMPDirectiveName(Kind) << VD;
3050 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3059 (!getCurLexicalContext()->isFileContext() ||
3060 !getCurLexicalContext()->Encloses(CanonicalVD->
getDeclContext()))) {
3061 Diag(
Id.getLoc(), diag::err_omp_var_scope)
3062 << getOpenMPDirectiveName(Kind) << VD;
3066 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3074 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
3075 Diag(
Id.getLoc(), diag::err_omp_var_scope)
3076 << getOpenMPDirectiveName(Kind) << VD;
3080 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3088 if (Kind == OMPD_threadprivate && VD->
isUsed() &&
3090 Diag(
Id.getLoc(), diag::err_omp_var_used)
3091 << getOpenMPDirectiveName(Kind) << VD;
3106 CurContext->addDecl(D);
3113class LocalVarRefChecker final
3119 if (
const auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
3122 diag::err_omp_local_var_in_threadprivate_init)
3124 SemaRef.Diag(VD->
getLocation(), diag::note_defined_here)
3131 bool VisitStmt(
const Stmt *S) {
3132 for (
const Stmt *Child : S->children()) {
3133 if (Child && Visit(Child))
3138 explicit LocalVarRefChecker(
Sema &SemaRef) : SemaRef(SemaRef) {}
3145 for (
Expr *RefExpr : VarList) {
3163 if (RequireCompleteType(ILoc, VD->
getType(),
3164 diag::err_omp_threadprivate_incomplete_type)) {
3171 Diag(ILoc, diag::err_omp_ref_type_arg)
3172 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->
getType();
3176 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3184 !(VD->
hasAttr<OMPThreadPrivateDeclAttr>() &&
3185 getLangOpts().OpenMPUseTLS &&
3186 getASTContext().getTargetInfo().isTLSSupported())) ||
3189 Diag(ILoc, diag::err_omp_var_thread_local)
3194 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3202 LocalVarRefChecker Checker(*
this);
3203 if (Checker.Visit(Init))
3207 Vars.push_back(RefExpr);
3208 DSAStack->addDSA(VD, DE, OMPC_threadprivate);
3209 VD->
addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
3212 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
3215 if (!Vars.empty()) {
3223static OMPAllocateDeclAttr::AllocatorTypeTy
3226 return OMPAllocateDeclAttr::OMPNullMemAlloc;
3227 if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3228 Allocator->isInstantiationDependent() ||
3229 Allocator->containsUnexpandedParameterPack())
3230 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3231 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3232 const Expr *AE = Allocator->IgnoreParenImpCasts();
3233 for (
int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
3234 auto AllocatorKind =
static_cast<OMPAllocateDeclAttr::AllocatorTypeTy
>(I);
3235 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
3236 llvm::FoldingSetNodeID AEId, DAEId;
3239 if (AEId == DAEId) {
3240 AllocatorKindRes = AllocatorKind;
3244 return AllocatorKindRes;
3249 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
Expr *Allocator) {
3250 if (!VD->
hasAttr<OMPAllocateDeclAttr>())
3252 const auto *A = VD->
getAttr<OMPAllocateDeclAttr>();
3253 Expr *PrevAllocator = A->getAllocator();
3254 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
3256 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
3257 if (AllocatorsMatch &&
3258 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
3259 Allocator && PrevAllocator) {
3260 const Expr *AE = Allocator->IgnoreParenImpCasts();
3262 llvm::FoldingSetNodeID AEId, PAEId;
3265 AllocatorsMatch = AEId == PAEId;
3267 if (!AllocatorsMatch) {
3269 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3273 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3275 PrevAllocator->printPretty(PrevAllocatorStream,
nullptr,
3279 Allocator ? Allocator->getExprLoc() : RefExpr->
getExprLoc();
3281 Allocator ? Allocator->getSourceRange() : RefExpr->
getSourceRange();
3283 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
3285 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
3286 S.
Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3287 << (Allocator ? 1 : 0) << AllocatorStream.str()
3288 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
3290 S.
Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3291 << PrevAllocatorRange;
3299 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3301 if (VD->
hasAttr<OMPAllocateDeclAttr>())
3310 (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3311 Allocator->isInstantiationDependent() ||
3312 Allocator->containsUnexpandedParameterPack()))
3314 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.
Context, AllocatorKind,
3315 Allocator, Alignment, SR);
3318 ML->DeclarationMarkedOpenMPAllocate(VD, A);
3325 assert(Clauses.size() <= 2 &&
"Expected at most two clauses.");
3326 Expr *Alignment =
nullptr;
3327 Expr *Allocator =
nullptr;
3328 if (Clauses.empty()) {
3333 if (LangOpts.OpenMPIsDevice &&
3335 targetDiag(Loc, diag::err_expected_allocator_clause);
3338 if (
const auto *AC = dyn_cast<OMPAllocatorClause>(
C))
3339 Allocator = AC->getAllocator();
3340 else if (
const auto *AC = dyn_cast<OMPAlignClause>(
C))
3341 Alignment = AC->getAlignment();
3343 llvm_unreachable(
"Unexpected clause on allocate directive");
3345 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3348 for (
Expr *RefExpr : VarList) {
3354 VD->
hasAttr<OMPThreadPrivateDeclAttr>() ||
3362 AllocatorKind, Allocator))
3370 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3371 Diag(Allocator->getExprLoc(),
3372 diag::err_omp_expected_predefined_allocator)
3373 << Allocator->getSourceRange();
3377 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3383 Vars.push_back(RefExpr);
3390 Owner = getCurLexicalContext();
3401 if (!CurContext->isFileContext()) {
3402 Diag(Loc, diag::err_omp_invalid_scope) <<
"requires";
3404 D = CheckOMPRequiresDecl(Loc, ClauseList);
3406 CurContext->addDecl(D);
3416 bool SkippedClauses) {
3417 if (!SkippedClauses && Assumptions.empty())
3418 Diag(Loc, diag::err_omp_no_clause_for_directive)
3419 << llvm::omp::getAllAssumeClauseOptions()
3420 << llvm::omp::getOpenMPDirectiveName(DKind);
3422 auto *AA = AssumptionAttr::Create(Context, llvm::join(Assumptions,
","), Loc);
3423 if (DKind == llvm::omp::Directive::OMPD_begin_assumes) {
3424 OMPAssumeScoped.push_back(AA);
3429 if (Assumptions.empty())
3432 assert(DKind == llvm::omp::Directive::OMPD_assumes &&
3433 "Unexpected omp assumption directive!");
3434 OMPAssumeGlobal.push_back(AA);
3441 auto *Ctx = CurContext;
3442 while (Ctx->getLexicalParent())
3443 Ctx = Ctx->getLexicalParent();
3444 DeclContexts.push_back(Ctx);
3445 while (!DeclContexts.empty()) {
3447 for (
auto *SubDC : DC->
decls()) {
3448 if (SubDC->isInvalidDecl())
3450 if (
auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) {
3451 DeclContexts.push_back(CTD->getTemplatedDecl());
3452 llvm::append_range(DeclContexts, CTD->specializations());
3455 if (
auto *DC = dyn_cast<DeclContext>(SubDC))
3456 DeclContexts.push_back(DC);
3457 if (
auto *F = dyn_cast<FunctionDecl>(SubDC)) {
3466 assert(isInOpenMPAssumeScope() &&
"Not in OpenMP assumes scope!");
3467 OMPAssumeScoped.pop_back();
3476 DSAStack->getEncounteredTargetLocs();
3478 if (!TargetLocations.empty() || !AtomicLoc.
isInvalid()) {
3479 for (
const OMPClause *CNew : ClauseList) {
3481 if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3482 isa<OMPUnifiedAddressClause>(CNew) ||
3483 isa<OMPReverseOffloadClause>(CNew) ||
3484 isa<OMPDynamicAllocatorsClause>(CNew)) {
3485 Diag(Loc, diag::err_omp_directive_before_requires)
3486 <<
"target" << getOpenMPClauseName(CNew->getClauseKind());
3488 Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3492 isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
3493 Diag(Loc, diag::err_omp_directive_before_requires)
3494 <<
"atomic" << getOpenMPClauseName(CNew->getClauseKind());
3495 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3501 if (!
DSAStack->hasDuplicateRequiresClause(ClauseList))
3509 const DSAStackTy::DSAVarData &DVar,
3510 bool IsLoopIterVar) {
3512 SemaRef.
Diag(DVar.RefExpr->
getExprLoc(), diag::note_omp_explicit_dsa)
3513 << getOpenMPClauseName(DVar.CKind);
3517 PDSA_StaticMemberShared,
3518 PDSA_StaticLocalVarShared,
3519 PDSA_LoopIterVarPrivate,
3520 PDSA_LoopIterVarLinear,
3521 PDSA_LoopIterVarLastprivate,
3522 PDSA_ConstVarShared,
3523 PDSA_GlobalVarShared,
3524 PDSA_TaskVarFirstprivate,
3525 PDSA_LocalVarPrivate,
3527 } Reason = PDSA_Implicit;
3528 bool ReportHint =
false;
3530 auto *VD = dyn_cast<VarDecl>(D);
3531 if (IsLoopIterVar) {
3532 if (DVar.CKind == OMPC_private)
3533 Reason = PDSA_LoopIterVarPrivate;
3534 else if (DVar.CKind == OMPC_lastprivate)
3535 Reason = PDSA_LoopIterVarLastprivate;
3537 Reason = PDSA_LoopIterVarLinear;
3539 DVar.CKind == OMPC_firstprivate) {
3540 Reason = PDSA_TaskVarFirstprivate;
3541 ReportLoc = DVar.ImplicitDSALoc;
3543 Reason = PDSA_StaticLocalVarShared;
3545 Reason = PDSA_StaticMemberShared;
3547 Reason = PDSA_GlobalVarShared;
3549 Reason = PDSA_ConstVarShared;
3550 else if (VD && VD->
isLocalVarDecl() && DVar.CKind == OMPC_private) {
3552 Reason = PDSA_LocalVarPrivate;
3554 if (Reason != PDSA_Implicit) {
3555 SemaRef.
Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3556 << Reason << ReportHint
3557 << getOpenMPDirectiveName(Stack->getCurrentDirective());
3558 }
else if (DVar.ImplicitDSALoc.
isValid()) {
3559 SemaRef.
Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3560 << getOpenMPClauseName(DVar.CKind);
3566 bool IsAggregateOrDeclareTarget) {
3569 case OMPC_DEFAULTMAP_MODIFIER_alloc:
3570 Kind = OMPC_MAP_alloc;
3572 case OMPC_DEFAULTMAP_MODIFIER_to:
3575 case OMPC_DEFAULTMAP_MODIFIER_from:
3576 Kind = OMPC_MAP_from;
3578 case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3579 Kind = OMPC_MAP_tofrom;
3581 case OMPC_DEFAULTMAP_MODIFIER_present:
3587 Kind = OMPC_MAP_alloc;
3589 case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3591 llvm_unreachable(
"Unexpected defaultmap implicit behavior");
3592 case OMPC_DEFAULTMAP_MODIFIER_none:
3593 case OMPC_DEFAULTMAP_MODIFIER_default:
3598 if (IsAggregateOrDeclareTarget) {
3599 Kind = OMPC_MAP_tofrom;
3602 llvm_unreachable(
"Unexpected defaultmap implicit behavior");
3609class DSAAttrChecker final :
public StmtVisitor<DSAAttrChecker, void> {
3612 bool ErrorFound =
false;
3613 bool TryCaptureCXXThisMembers =
false;
3615 const static unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
3620 ImplicitMapModifier[DefaultmapKindNum];
3622 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
3626 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
3628 if (S->getDirectiveKind() == OMPD_atomic ||
3629 S->getDirectiveKind() == OMPD_critical ||
3630 S->getDirectiveKind() == OMPD_section ||
3631 S->getDirectiveKind() == OMPD_master ||
3632 S->getDirectiveKind() == OMPD_masked ||
3634 Visit(S->getAssociatedStmt());
3637 visitSubCaptures(S->getInnermostCapturedStmt());
3640 if (TryCaptureCXXThisMembers ||
3642 llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3644 return C.capturesThis();
3646 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3647 TryCaptureCXXThisMembers =
true;
3648 Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3649 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3656 if (
auto *FC = dyn_cast<OMPFirstprivateClause>(
C)) {
3657 for (
Expr *Ref : FC->varlists())
3669 if (
auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
3672 !Stack->getTopDSA(VD,
false).RefExpr &&
3673 !Stack->isImplicitDefaultFirstprivateFD(VD))) {
3674 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3675 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3676 Visit(CED->getInit());
3679 }
else if (VD->
isImplicit() || isa<OMPCapturedExprDecl>(VD))
3682 if (!Stack->isImplicitDefaultFirstprivateFD(VD))
3687 !Stack->isImplicitDefaultFirstprivateFD(VD) &&
3688 !Stack->isImplicitTaskFirstprivate(VD))
3691 if (Stack->isUsesAllocatorsDecl(VD))
3694 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD,
false);
3696 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3701 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3704 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
3705 !Stack->isImplicitDefaultFirstprivateFD(VD) &&
3706 !Stack->isImplicitTaskFirstprivate(VD))
3715 if (DVar.CKind == OMPC_unknown &&
3716 (Stack->getDefaultDSA() == DSA_none ||
3717 Stack->getDefaultDSA() == DSA_private ||
3718 Stack->getDefaultDSA() == DSA_firstprivate) &&
3719 isImplicitOrExplicitTaskingRegion(DKind) &&
3720 VarsWithInheritedDSA.count(VD) == 0) {
3721 bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3722 if (!InheritedDSA && (Stack->getDefaultDSA() == DSA_firstprivate ||
3723 Stack->getDefaultDSA() == DSA_private)) {
3724 DSAStackTy::DSAVarData DVar =
3725 Stack->getImplicitDSA(VD,
false);
3726 InheritedDSA = DVar.CKind == OMPC_unknown;
3729 VarsWithInheritedDSA[VD] = E;
3730 if (Stack->getDefaultDSA() == DSA_none)
3745 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3746 OMPC_DEFAULTMAP_MODIFIER_none;
3747 if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3748 VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3752 if (!Stack->checkMappableExprComponentListsForDecl(
3757 auto MI = MapExprComponents.rbegin();
3758 auto ME = MapExprComponents.rend();
3759 return MI != ME && MI->getAssociatedDeclaration() == VD;
3761 VarsWithInheritedDSA[VD] = E;
3767 bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) ==
3768 OMPC_DEFAULTMAP_MODIFIER_present;
3769 if (IsModifierPresent) {
3770 if (llvm::find(ImplicitMapModifier[ClauseKind],
3771 OMPC_MAP_MODIFIER_present) ==
3772 std::end(ImplicitMapModifier[ClauseKind])) {
3773 ImplicitMapModifier[ClauseKind].push_back(
3774 OMPC_MAP_MODIFIER_present);
3780 !Stack->isLoopControlVariable(VD).first) {
3781 if (!Stack->checkMappableExprComponentListsForDecl(
3786 if (SemaRef.LangOpts.OpenMP >= 50)
3787 return !StackComponents.empty();
3790 return StackComponents.size() == 1 ||
3792 std::next(StackComponents.rbegin()),
3793 StackComponents.rend(),
3794 [](const OMPClauseMappableExprCommon::
3795 MappableComponent &MC) {
3796 return MC.getAssociatedDeclaration() ==
3798 (isa<OMPArraySectionExpr>(
3799 MC.getAssociatedExpression()) ||
3800 isa<OMPArrayShapingExpr>(
3801 MC.getAssociatedExpression()) ||
3802 isa<ArraySubscriptExpr>(
3803 MC.getAssociatedExpression()));
3806 bool IsFirstprivate =
false;
3808 if (
const auto *RD =
3810 IsFirstprivate = RD->isLambda();
3812 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3813 if (IsFirstprivate) {
3814 ImplicitFirstprivate.emplace_back(E);
3817 Stack->getDefaultmapModifier(ClauseKind);
3819 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3820 ImplicitMap[ClauseKind][Kind].emplace_back(E);
3830 DVar = Stack->hasInnermostDSA(
3833 return C == OMPC_reduction && !AppliedToPointee;
3842 SemaRef.
Diag(ELoc, diag::err_omp_reduction_in_task);
3848 DVar = Stack->getImplicitDSA(VD,
false);
3850 (((Stack->getDefaultDSA() == DSA_firstprivate &&
3851 DVar.CKind == OMPC_firstprivate) ||
3852 (Stack->getDefaultDSA() == DSA_private &&
3853 DVar.CKind == OMPC_private)) &&
3855 !Stack->isLoopControlVariable(VD).first) {
3856 if (Stack->getDefaultDSA() == DSA_private)
3857 ImplicitPrivate.push_back(E);
3859 ImplicitFirstprivate.push_back(E);
3866 *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3867 Stack->addToParentTargetRegionLinkGlobals(E);
3881 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD,
false);
3884 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3888 !Stack->isLoopControlVariable(FD).first &&
3889 !Stack->checkMappableExprComponentListsForDecl(
3894 return isa<CXXThisExpr>(
3896 StackComponents.back().getAssociatedExpression())
3908 if (Stack->isClassPreviouslyMapped(TE->getType()))
3912 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3917 ImplicitMap[ClauseKind][Kind].emplace_back(E);
3926 DVar = Stack->hasInnermostDSA(
3929 return C == OMPC_reduction && !AppliedToPointee;
3938 SemaRef.
Diag(ELoc, diag::err_omp_reduction_in_task);
3944 DVar = Stack->getImplicitDSA(FD,
false);
3946 !Stack->isLoopControlVariable(FD).first) {
3951 if (DVar.CKind != OMPC_unknown)
3952 ImplicitFirstprivate.push_back(E);
3959 Stack->getCurrentDirective(),
3963 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
3964 if (!Stack->checkMappableExprComponentListsForDecl(
3970 auto CCI = CurComponents.rbegin();
3971 auto CCE = CurComponents.rend();
3972 for (const auto &SC : llvm::reverse(StackComponents)) {
3974 if (CCI->getAssociatedExpression()->getStmtClass() !=
3975 SC.getAssociatedExpression()->getStmtClass())
3976 if (!((isa<OMPArraySectionExpr>(
3977 SC.getAssociatedExpression()) ||
3978 isa<OMPArrayShapingExpr>(
3979 SC.getAssociatedExpression())) &&
3980 isa<ArraySubscriptExpr>(
3981 CCI->getAssociatedExpression())))
3984 const Decl *CCD = CCI->getAssociatedDeclaration();
3985 const Decl *SCD = SC.getAssociatedDeclaration();
3986 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
3987 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
3990 std::advance(CCI, 1);
3998 }
else if (!TryCaptureCXXThisMembers) {
4006 if (isa_and_nonnull<OMPPrivateClause>(
C))
4012 if (
C && !((isa<OMPFirstprivateClause>(
C) || isa<OMPMapClause>(
C)) &&
4022 VisitSubCaptures(S);
4031 for (
Stmt *
C : S->arguments()) {
4038 if (
Expr *Callee = S->getCallee())
4039 if (
auto *CE = dyn_cast<MemberExpr>(
Callee->IgnoreParenImpCasts()))
4040 Visit(CE->getBase());
4042 void VisitStmt(
Stmt *S) {
4043 for (
Stmt *
C : S->children()) {
4054 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
4056 VarDecl *VD = Cap.getCapturedVar();
4060 Stack->checkMappableExprComponentListsForDecl(
4067 Cap.getLocation(),
true);
4071 bool isErrorFound()
const {
return ErrorFound; }
4073 return ImplicitFirstprivate;
4078 return ImplicitMap[DK][MK];
4082 return ImplicitMapModifier[Kind];
4085 return VarsWithInheritedDSA;
4089 : Stack(S), SemaRef(SemaRef), ErrorFound(
false), CS(CS) {
4092 for (DeclRefExpr *E : Stack->getLinkGlobals())
4104 Traits.emplace_back(llvm::omp::TraitProperty::construct_target_target);
4106 Traits.emplace_back(llvm::omp::TraitProperty::construct_teams_teams);
4108 Traits.emplace_back(llvm::omp::TraitProperty::construct_parallel_parallel);
4110 Traits.emplace_back(llvm::omp::TraitProperty::construct_for_for);
4112 Traits.emplace_back(llvm::omp::TraitProperty::construct_simd_simd);
4113 Stack->handleConstructTrait(Traits, ScopeEntry);
4119 case OMPD_parallel_for:
4120 case OMPD_parallel_for_simd:
4121 case OMPD_parallel_sections:
4122 case OMPD_parallel_master:
4123 case OMPD_parallel_masked:
4124 case OMPD_parallel_loop:
4126 case OMPD_teams_distribute:
4127 case OMPD_teams_distribute_simd: {
4132 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4133 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4134 std::make_pair(StringRef(),
QualType())
4140 case OMPD_target_teams:
4141 case OMPD_target_parallel:
4142 case OMPD_target_parallel_for:
4143 case OMPD_target_parallel_for_simd:
4144 case OMPD_target_teams_loop:
4145 case OMPD_target_parallel_loop:
4146 case OMPD_target_teams_distribute:
4147 case OMPD_target_teams_distribute_simd: {
4157 std::make_pair(
".global_tid.", KmpInt32Ty),
4158 std::make_pair(
".part_id.", KmpInt32PtrTy),
4159 std::make_pair(
".privates.", VoidPtrTy),
4164 std::make_pair(StringRef(),
QualType())
4170 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4171 AlwaysInlineAttr::CreateImplicit(
4173 AlwaysInlineAttr::Keyword_forceinline));
4175 std::make_pair(StringRef(),
QualType())
4181 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4182 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4183 std::make_pair(StringRef(),
QualType())
4188 ParamsTeamsOrParallel, 2);
4192 case OMPD_target_simd: {
4202 std::make_pair(
".global_tid.", KmpInt32Ty),
4203 std::make_pair(
".part_id.", KmpInt32PtrTy),
4204 std::make_pair(
".privates.", VoidPtrTy),
4209 std::make_pair(StringRef(),
QualType())
4215 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4216 AlwaysInlineAttr::CreateImplicit(
4218 AlwaysInlineAttr::Keyword_forceinline));
4220 std::make_pair(StringRef(),
QualType()),
4240 case OMPD_taskgroup:
4241 case OMPD_distribute:
4242 case OMPD_distribute_simd:
4244 case OMPD_target_data:
4245 case OMPD_dispatch: {
4247 std::make_pair(StringRef(),
QualType())
4263 std::make_pair(
".global_tid.", KmpInt32Ty),
4264 std::make_pair(
".part_id.", KmpInt32PtrTy),
4265 std::make_pair(
".privates.", VoidPtrTy),
4270 std::make_pair(StringRef(),
QualType())
4276 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4277 AlwaysInlineAttr::CreateImplicit(
4279 AlwaysInlineAttr::Keyword_forceinline));
4283 case OMPD_taskloop_simd:
4284 case OMPD_master_taskloop:
4285 case OMPD_masked_taskloop:
4286 case OMPD_masked_taskloop_simd:
4287 case OMPD_master_taskloop_simd: {
4305 std::make_pair(
".global_tid.", KmpInt32Ty),
4306 std::make_pair(
".part_id.", KmpInt32PtrTy),
4307 std::make_pair(
".privates.", VoidPtrTy),
4312 std::make_pair(
".lb.", KmpUInt64Ty),
4313 std::make_pair(
".ub.", KmpUInt64Ty),
4314 std::make_pair(
".st.", KmpInt64Ty),
4315 std::make_pair(
".liter.", KmpInt32Ty),
4316 std::make_pair(
".reductions.", VoidPtrTy),
4317 std::make_pair(StringRef(),
QualType())
4323 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4324 AlwaysInlineAttr::CreateImplicit(
4326 AlwaysInlineAttr::Keyword_forceinline));
4329 case OMPD_parallel_masked_taskloop:
4330 case OMPD_parallel_masked_taskloop_simd:
4331 case OMPD_parallel_master_taskloop:
4332 case OMPD_parallel_master_taskloop_simd: {
4346 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4347 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4348 std::make_pair(StringRef(),
QualType())
4358 std::make_pair(
".global_tid.", KmpInt32Ty),
4359 std::make_pair(
".part_id.", KmpInt32PtrTy),
4360 std::make_pair(
".privates.", VoidPtrTy),
4365 std::make_pair(
".lb.", KmpUInt64Ty),
4366 std::make_pair(
".ub.", KmpUInt64Ty),
4367 std::make_pair(
".st.", KmpInt64Ty),
4368 std::make_pair(
".liter.", KmpInt32Ty),
4369 std::make_pair(
".reductions.", VoidPtrTy),
4370 std::make_pair(StringRef(),
QualType())
4376 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4377 AlwaysInlineAttr::CreateImplicit(
4379 AlwaysInlineAttr::Keyword_forceinline));
4382 case OMPD_distribute_parallel_for_simd:
4383 case OMPD_distribute_parallel_for: {
4388 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4389 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4392 std::make_pair(StringRef(),
QualType())
4398 case OMPD_target_teams_distribute_parallel_for:
4399 case OMPD_target_teams_distribute_parallel_for_simd: {
4410 std::make_pair(
".global_tid.", KmpInt32Ty),
4411 std::make_pair(
".part_id.", KmpInt32PtrTy),
4412 std::make_pair(
".privates.", VoidPtrTy),
4417 std::make_pair(StringRef(),
QualType())
4423 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4424 AlwaysInlineAttr::CreateImplicit(
4426 AlwaysInlineAttr::Keyword_forceinline));
4428 std::make_pair(StringRef(),
QualType())
4435 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4436 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4437 std::make_pair(StringRef(),
QualType())
4444 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4445 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4448 std::make_pair(StringRef(),
QualType())
4457 case OMPD_teams_loop: {
4463 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4464 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4465 std::make_pair(StringRef(),
QualType())
4473 case OMPD_teams_distribute_parallel_for:
4474 case OMPD_teams_distribute_parallel_for_simd: {
4480 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4481 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4482 std::make_pair(StringRef(),
QualType())
4489 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4490 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4493 std::make_pair(StringRef(),
QualType())
4501 case OMPD_target_update:
4502 case OMPD_target_enter_data:
4503 case OMPD_target_exit_data: {
4513 std::make_pair(
".global_tid.", KmpInt32Ty),
4514 std::make_pair(
".part_id.", KmpInt32PtrTy),
4515 std::make_pair(
".privates.", VoidPtrTy),
4520 std::make_pair(StringRef(),
QualType())
4526 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4527 AlwaysInlineAttr::CreateImplicit(
4529 AlwaysInlineAttr::Keyword_forceinline));
4532 case OMPD_threadprivate:
4534 case OMPD_taskyield:
4537 case OMPD_cancellation_point:
4542 case OMPD_declare_reduction:
4543 case OMPD_declare_mapper:
4544 case OMPD_declare_simd:
4545 case OMPD_declare_target:
4546 case OMPD_end_declare_target:
4548 case OMPD_declare_variant:
4549 case OMPD_begin_declare_variant:
4550 case OMPD_end_declare_variant:
4551 case OMPD_metadirective:
4552 llvm_unreachable(
"OpenMP Directive is not allowed");
4555 llvm_unreachable(
"Unknown OpenMP directive");
4561int Sema::getNumberOfConstructScopes(
unsigned Level)
const {
4562 return getOpenMPCaptureLevels(
DSAStack->getDirective(Level));
4568 return CaptureRegions.size();
4572 Expr *CaptureExpr,
bool WithInit,
4574 bool AsExpression) {
4575 assert(CaptureExpr);
4581 Ty =
C.getLValueReferenceType(Ty);
4583 Ty =
C.getPointerType(Ty);
4595 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(
C));
4644class CaptureRegionUnwinderRAII {
4651 CaptureRegionUnwinderRAII(
Sema &S,
bool &ErrorFound,
4653 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
4654 ~CaptureRegionUnwinderRAII() {
4657 while (--ThisCaptureLevel >= 0)
4667 if (!CurContext->isDependentContext() &&
4670 DSAStack->getCurrentDirective()))) {
4672 if (
const auto *RD =
Type.getCanonicalType()
4673 .getNonReferenceType()
4675 bool SavedForceCaptureByReferenceInTargetExecutable =
4676 DSAStack->isForceCaptureByReferenceInTargetExecutable();
4677 DSAStack->setForceCaptureByReferenceInTargetExecutable(
4679 if (RD->isLambda()) {
4680 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
4682 RD->getCaptureFields(Captures, ThisCapture);
4685 VarDecl *VD = LC.getCapturedVar();
4689 MarkVariableReferenced(LC.getLocation(), VD);
4690 }
else if (LC.getCaptureKind() ==
LCK_This) {
4691 QualType ThisTy = getCurrentThisType();
4694 CheckCXXThisCapture(LC.getLocation());
4698 DSAStack->setForceCaptureByReferenceInTargetExecutable(
4699 SavedForceCaptureByReferenceInTargetExecutable);
4709 for (
const OMPClause *Clause : Clauses) {
4710 if (Clause->getClauseKind() == OMPC_ordered)
4712 else if (Clause->getClauseKind() == OMPC_order) {
4714 if (Order->
getKind() != OMPC_ORDER_concurrent)
4717 if (Ordered && Order)
4721 if (Ordered && Order) {
4723 diag::err_omp_simple_clause_incompatible_with_ordered)
4724 << getOpenMPClauseName(OMPC_order)
4738 if (
DSAStack->getCurrentDirective() == OMPD_atomic ||
4739 DSAStack->getCurrentDirective() == OMPD_critical ||
4740 DSAStack->getCurrentDirective() == OMPD_section ||
4741 DSAStack->getCurrentDirective() == OMPD_master ||
4742 DSAStack->getCurrentDirective() == OMPD_masked)
4745 bool ErrorFound =
false;
4746 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4747 *
this, ErrorFound,
DSAStack->getCurrentDirective());
4748 if (!S.isUsable()) {
4761 if (!LangOpts.OpenMPSimd &&
4763 DSAStack->getCurrentDirective() == OMPD_target) &&
4764 Clause->getClauseKind() == OMPC_in_reduction) {
4768 for (
Expr *E : IRC->taskgroup_descriptors())
4770 MarkDeclarationsReferencedInExpr(E);
4773 Clause->getClauseKind() == OMPC_copyprivate ||
4774 (getLangOpts().OpenMPUseTLS &&
4775 getASTContext().getTargetInfo().isTLSSupported() &&
4776 Clause->getClauseKind() == OMPC_copyin)) {
4777 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
4780 if (
auto *E = cast_or_null<Expr>(VarRef)) {
4781 MarkDeclarationsReferencedInExpr(E);
4784 DSAStack->setForceVarCapturing(
false);
4786 DSAStack->getCurrentDirective())) {
4787 assert(CaptureRegions.empty() &&
4788 "No captured regions in loop transformation directives.");
4789 }
else if (CaptureRegions.size() > 1 ||
4790 CaptureRegions.back() != OMPD_unknown) {
4794 if (
Expr *E =
C->getPostUpdateExpr())
4795 MarkDeclarationsReferencedInExpr(E);
4798 if (Clause->getClauseKind() == OMPC_schedule)
4800 else if (Clause->getClauseKind() == OMPC_ordered)
4802 else if (Clause->getClauseKind() == OMPC_linear)
4803 LCs.push_back(cast<OMPLinearClause>(Clause));
4807 MarkDeclarationsReferencedInExpr(E);
4814 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4819 diag::err_omp_simple_clause_incompatible_with_ordered)
4820 << getOpenMPClauseName(OMPC_schedule)
4822 OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4833 Diag(
C->getBeginLoc(), diag::err_omp_linear_ordered)
4842 << getOpenMPDirectiveName(
DSAStack->getCurrentDirective());
4849 unsigned CompletedRegions = 0;
4854 if (ThisCaptureRegion != OMPD_unknown) {
4862 if (CaptureRegion == ThisCaptureRegion ||
4863 CaptureRegion == OMPD_unknown) {
4864 if (
auto *DS = cast_or_null<DeclStmt>(
C->getPreInitStmt())) {
4865 for (
Decl *D : DS->decls())
4866 MarkVariableReferenced(D->
getLocation(), cast<VarDecl>(D));
4871 if (ThisCaptureRegion == OMPD_target) {
4875 if (
const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(
C)) {
4876 for (
unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4880 MarkDeclarationsReferencedInExpr(E);
4886 if (ThisCaptureRegion == OMPD_parallel) {
4890 if (
auto *RC = dyn_cast<OMPReductionClause>(
C)) {
4891 if (RC->getModifier() != OMPC_REDUCTION_inscan)
4893 for (
Expr *E : RC->copy_array_temps())
4894 MarkDeclarationsReferencedInExpr(E);
4896 if (
auto *AC = dyn_cast<OMPAlignedClause>(
C)) {
4897 for (
Expr *E : AC->varlists())
4898 MarkDeclarationsReferencedInExpr(E);
4902 if (++CompletedRegions == CaptureRegions.size())
4904 SR = ActOnCapturedRegionEnd(SR.
get());
4913 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
4916 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
4917 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
4920 SemaRef.
Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4921 << getOpenMPDirectiveName(CancelRegion);
4931 if (Stack->getCurScope()) {
4934 bool NestingProhibited =
false;
4935 bool CloseNesting =
true;
4936 bool OrphanSeen =
false;
4939 ShouldBeInParallelRegion,
4940 ShouldBeInOrderedRegion,
4941 ShouldBeInTargetRegion,
4942 ShouldBeInTeamsRegion,
4943 ShouldBeInLoopSimdRegion,
4944 } Recommend = NoRecommend;
4946 ((SemaRef.
LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
4947 (SemaRef.
LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
4948 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
4949 CurrentRegion != OMPD_scan))) {
4962 SemaRef.
Diag(StartLoc, (CurrentRegion != OMPD_simd)
4963 ? diag::err_omp_prohibited_region_simd
4964 : diag::warn_omp_nesting_simd)
4965 << (SemaRef.
LangOpts.OpenMP >= 50 ? 1 : 0);
4966 return CurrentRegion != OMPD_simd;
4968 if (ParentRegion == OMPD_atomic) {
4971 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
4974 if (CurrentRegion == OMPD_section) {
4979 if (ParentRegion != OMPD_sections &&
4980 ParentRegion != OMPD_parallel_sections) {
4981 SemaRef.
Diag(StartLoc, diag::err_omp_orphaned_section_directive)
4982 << (ParentRegion != OMPD_unknown)
4983 << getOpenMPDirectiveName(ParentRegion);
4991 if (ParentRegion == OMPD_unknown &&
4993 CurrentRegion != OMPD_cancellation_point &&
4994 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
4996 if (CurrentRegion == OMPD_cancellation_point ||
4997 CurrentRegion == OMPD_cancel) {
5010 !((CancelRegion == OMPD_parallel &&
5011 (ParentRegion == OMPD_parallel ||
5012 ParentRegion == OMPD_target_parallel)) ||
5013 (CancelRegion == OMPD_for &&
5014 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
5015 ParentRegion == OMPD_target_parallel_for ||
5016 ParentRegion == OMPD_distribute_parallel_for ||
5017 ParentRegion == OMPD_teams_distribute_parallel_for ||
5018 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
5019 (CancelRegion == OMPD_taskgroup &&
5020 (ParentRegion == OMPD_task ||
5022 (ParentRegion == OMPD_taskloop ||
5023 ParentRegion == OMPD_master_taskloop ||
5024 ParentRegion == OMPD_masked_taskloop ||
5025 ParentRegion == OMPD_parallel_masked_taskloop ||
5026 ParentRegion == OMPD_parallel_master_taskloop)))) ||
5027 (CancelRegion == OMPD_sections &&
5028 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
5029 ParentRegion == OMPD_parallel_sections)));
5030 OrphanSeen = ParentRegion == OMPD_unknown;
5031 }
else if (CurrentRegion == OMPD_master || CurrentRegion == OMPD_masked) {
5038 }
else if (CurrentRegion == OMPD_critical && CurrentName.
getName()) {
5044 bool DeadLock = Stack->hasDirective(
5048 if (K == OMPD_critical && DNI.
getName() == CurrentName.
getName()) {
5049 PreviousCriticalLoc = Loc;
5056 SemaRef.
Diag(StartLoc,
5057 diag::err_omp_prohibited_region_critical_same_name)
5059 if (PreviousCriticalLoc.
isValid())
5060 SemaRef.
Diag(PreviousCriticalLoc,
5061 diag::note_omp_previous_critical_region);
5064 }
else if (CurrentRegion == OMPD_barrier) {
5072 ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
5073 ParentRegion == OMPD_parallel_master ||
5074 ParentRegion == OMPD_parallel_masked ||
5075 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
5087 ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
5088 ParentRegion == OMPD_parallel_master ||
5089 ParentRegion == OMPD_parallel_masked ||
5090 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
5091 Recommend = ShouldBeInParallelRegion;
5092 }
else if (CurrentRegion == OMPD_ordered) {
5101 NestingProhibited = ParentRegion == OMPD_critical ||
5104 Stack->isParentOrderedRegion());
5105 Recommend = ShouldBeInOrderedRegion;
5111 (SemaRef.
LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
5112 (SemaRef.
LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
5113 ParentRegion != OMPD_target);
5114 OrphanSeen = ParentRegion == OMPD_unknown;
5115 Recommend = ShouldBeInTargetRegion;
5116 }
else if (CurrentRegion == OMPD_scan) {
5122 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
5123 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
5124 ParentRegion != OMPD_parallel_for_simd);
5125 OrphanSeen = ParentRegion == OMPD_unknown;
5126 Recommend = ShouldBeInLoopSimdRegion;
5128 if (!NestingProhibited &&
5131 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
5143 CurrentRegion != OMPD_loop &&
5145 CurrentRegion == OMPD_atomic);
5146 Recommend = ShouldBeInParallelRegion;
5148 if (!NestingProhibited && CurrentRegion == OMPD_loop) {
5153 NestingProhibited = BindKind == OMPC_BIND_teams &&
5154 ParentRegion != OMPD_teams &&
5155 ParentRegion != OMPD_target_teams;
5156 Recommend = ShouldBeInTeamsRegion;
5158 if (!NestingProhibited &&
5164 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
5165 Recommend = ShouldBeInTeamsRegion;
5167 if (!NestingProhibited &&
5174 NestingProhibited = Stack->hasDirective(
5178 OffendingRegion = K;
5184 CloseNesting =
false;
5186 if (NestingProhibited) {
5188 SemaRef.
Diag(StartLoc, diag::err_omp_orphaned_device_directive)
5189 << getOpenMPDirectiveName(CurrentRegion) << Recommend;
5191 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region)
5192 << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
5193 << Recommend << getOpenMPDirectiveName(CurrentRegion);
5208 bool ErrorFound =
false;
5209 unsigned NamedModifiersNumber = 0;
5210 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
5211 FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1);
5214 if (
const auto *IC = dyn_cast_or_null<OMPIfClause>(
C)) {
5218 if (FoundNameModifiers[CurNM]) {
5219 S.
Diag(
C->getBeginLoc(), diag::err_omp_more_one_clause)
5220 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
5221 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
5223 }
else if (CurNM != OMPD_unknown) {
5224 NameModifierLoc.push_back(IC->getNameModifierLoc());
5225 ++NamedModifiersNumber;
5227 FoundNameModifiers[CurNM] = IC;
5228 if (CurNM == OMPD_unknown)
5234 if (!llvm::is_contained(AllowedNameModifiers, CurNM)) {
5235 S.
Diag(IC->getNameModifierLoc(),
5236 diag::err_omp_wrong_if_directive_name_modifier)
5237 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
5244 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
5245 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
5246 S.
Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
5247 diag::err_omp_no_more_if_clause);
5250 std::string Sep(
", ");
5251 unsigned AllowedCnt = 0;
5252 unsigned TotalAllowedNum =
5253 AllowedNameModifiers.size() - NamedModifiersNumber;
5254 for (
unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
5257 if (!FoundNameModifiers[NM]) {
5259 Values += getOpenMPDirectiveName(NM);
5261 if (AllowedCnt + 2 == TotalAllowedNum)
5263 else if (AllowedCnt + 1 != TotalAllowedNum)
5268 S.
Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
5269 diag::err_omp_unnamed_if_clause)
5270 << (TotalAllowedNum > 1) << Values;
5273 S.
Diag(Loc, diag::note_omp_previous_named_if_clause);
5283 bool AllowArraySection) {
5286 return std::make_pair(
nullptr,
true);
5298 } IsArrayExpr = NoArrayExpr;
5299 if (AllowArraySection) {
5300 if (
auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
5301 Expr *
Base = ASE->getBase()->IgnoreParenImpCasts();
5302 while (
auto *TempASE = dyn_cast<ArraySubscriptExpr>(
Base))
5303 Base = TempASE->getBase()->IgnoreParenImpCasts();
5305 IsArrayExpr = ArraySubscript;
5306 }
else if (
auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
5307 Expr *
Base = OASE->getBase()->IgnoreParenImpCasts();
5308 while (
auto *TempOASE = dyn_cast<OMPArraySectionExpr>(
Base))
5309 Base = TempOASE->getBase()->IgnoreParenImpCasts();
5310 while (
auto *TempASE = dyn_cast<ArraySubscriptExpr>(
Base))
5311 Base = TempASE->getBase()->IgnoreParenImpCasts();
5313 IsArrayExpr = OMPArraySection;
5319 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
5320 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
5321 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
5323 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
5324 !isa<FieldDecl>(ME->getMemberDecl()))) {
5325 if (IsArrayExpr != NoArrayExpr) {
5326 S.
Diag(ELoc, diag::err_omp_expected_base_var_name)
5327 << IsArrayExpr << ERange;
5331 ? diag::err_omp_expected_var_name_member_expr_or_array_item
5332 : diag::err_omp_expected_var_name_member_expr)
5335 return std::make_pair(
nullptr,
false);
5337 return std::make_pair(
5344class AllocatorChecker final :
public ConstStmtVisitor<AllocatorChecker, bool> {
5345 DSAStackTy *S =
nullptr;
5349 return S->isUsesAllocatorsDecl(E->
getDecl())
5350 .value_or(DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
5351 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait;
5353 bool VisitStmt(
const Stmt *S) {
5354 for (
const Stmt *Child : S->children()) {
5355 if (Child && Visit(Child))
5360 explicit AllocatorChecker(DSAStackTy *S) : S(S) {}
5367 "Expected non-dependent context.");
5368 auto AllocateRange =
5371 auto PrivateRange = llvm::make_filter_range(Clauses, [](
const OMPClause *
C) {
5376 if (
Cl->getClauseKind() == OMPC_private) {
5378 I = PC->private_copies().begin();
5379 It = PC->varlist_begin();
5380 Et = PC->varlist_end();
5381 }
else if (
Cl->getClauseKind() == OMPC_firstprivate) {
5383 I = PC->private_copies().begin();
5384 It = PC->varlist_begin();
5385 Et = PC->varlist_end();
5386 }
else if (
Cl->getClauseKind() == OMPC_lastprivate) {
5388 I = PC->private_copies().begin();
5389 It = PC->varlist_begin();
5390 Et = PC->varlist_end();
5391 }
else if (
Cl->getClauseKind() == OMPC_linear) {
5393 I = PC->privates().begin();
5394 It = PC->varlist_begin();
5395 Et = PC->varlist_end();
5396 }
else if (
Cl->getClauseKind() == OMPC_reduction) {
5398 I = PC->privates().begin();
5399 It = PC->varlist_begin();
5400 Et = PC->varlist_end();
5401 }
else if (
Cl->getClauseKind() == OMPC_task_reduction) {
5403 I = PC->privates().begin();
5404 It = PC->varlist_begin();
5405 Et = PC->varlist_end();
5406 }
else if (
Cl->getClauseKind() == OMPC_in_reduction) {
5408 I = PC->privates().begin();
5409 It = PC->varlist_begin();
5410 Et = PC->varlist_end();
5412 llvm_unreachable(
"Expected private clause.");
5414 for (
Expr *E : llvm::make_range(It, Et)) {
5421 Expr *SimpleRefExpr = E;
5424 DeclToCopy.try_emplace(Res.first,
5425 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
5434 AC->getAllocator()) {
5435 Expr *Allocator = AC->getAllocator();
5441 AllocatorChecker Checker(Stack);
5442 if (Checker.Visit(Allocator))
5443 S.
Diag(Allocator->getExprLoc(),
5444 diag::err_omp_allocator_not_in_uses_allocators)
5445 << Allocator->getSourceRange();
5447 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
5453 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
5456 S.
Diag(AC->getAllocator()->getExprLoc(),
5457 diag::warn_omp_allocate_thread_on_task_target_directive)
5458 << getOpenMPDirectiveName(Stack->getCurrentDirective());
5460 for (
Expr *E : AC->varlists()) {
5463 Expr *SimpleRefExpr = E;
5466 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD,
false);
5469 diag::err_omp_expected_private_copy_for_allocate);
5472 VarDecl *PrivateVD = DeclToCopy[VD];
5474 AllocatorKind, AC->getAllocator()))
5477 Expr *Alignment =
nullptr;
5494 CaptureVars(
Sema &Actions) : BaseTransform(Actions) {}
5496 bool AlwaysRebuild() {
return true; }
5509 BodyStmts.push_back(NewDeclStmt);
5547 DistParam, LogicalTy,
VK_LValue, {},
nullptr,
nullptr, {},
nullptr);
5558 auto BuildVarRef = [&](
VarDecl *VD) {
5563 Ctx, llvm::APInt(Ctx.
getIntWidth(LogicalTy), 0), LogicalTy, {});
5565 Ctx, llvm::APInt(Ctx.
getIntWidth(LogicalTy), 1), LogicalTy, {});
5571 Actions.
BuildBinOp(
nullptr, {}, BO_LT, BuildVarRef(NewStep), Zero));
5575 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5579 nullptr, {}, BO_Div, ForwardRange, BuildVarRef(NewStep)));
5583 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5587 Actions.
BuildUnaryOp(
nullptr, {}, UO_Minus, BuildVarRef(NewStep)));
5589 Actions.
BuildBinOp(
nullptr, {}, BO_Div, BackwardRange, NegIncAmount));
5593 {}, {}, IsNegStep, BackwardDist, ForwardDist));
5595 assert((Rel == BO_LT || Rel == BO_LE || Rel == BO_GE || Rel == BO_GT) &&
5596 "Expected one of these relational operators");
5603 nullptr, {}, Rel, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5607 if (Rel == BO_GE || Rel == BO_GT)
5609 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5612 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5618 if (Rel == BO_LE || Rel == BO_GE) {
5629 Expr *Divisor = BuildVarRef(NewStep);
5630 if (Rel == BO_GE || Rel == BO_GT)
5633 Expr *DivisorMinusOne =
5636 Actions.
BuildBinOp(
nullptr, {}, BO_Add, Range, DivisorMinusOne));
5638 Actions.
BuildBinOp(
nullptr, {}, BO_Div, RangeRoundUp, Divisor));
5648 Actions.
getCurScope(), {}, BO_Assign, DistRef, Dist));
5649 BodyStmts.push_back(ResultAssign);
5681 {
"Logical", LogicalTy},
5692 assert(!
Invalid &&
"Expecting capture-by-value to work.");
5701 TargetParam, LoopVarTy,
VK_LValue, {},
nullptr,
nullptr, {},
nullptr);
5704 IndvarParam, LogicalTy,
VK_LValue, {},
nullptr,
nullptr, {},
nullptr);
5707 CaptureVars Recap(Actions);
5712 Actions.
BuildBinOp(
nullptr, {}, BO_Mul, NewStep, LogicalRef));
5727 BO_Assign, TargetRef, Advanced));
5740 if (
auto *For = dyn_cast<ForStmt>(AStmt)) {
5741 Stmt *Init = For->getInit();
5742 if (
auto *LCVarDeclStmt = dyn_cast<DeclStmt>(Init)) {
5745 }
else if (
auto *LCAssign = dyn_cast<BinaryOperator>(Init)) {
5747 assert(LCAssign->getOpcode() == BO_Assign &&
5748 "init part must be a loop variable assignment");
5752 llvm_unreachable(
"Cannot determine loop variable");
5755 Cond = For->getCond();
5756 Inc = For->getInc();
5757 }
else if (
auto *RangeFor = dyn_cast<CXXForRangeStmt>(AStmt)) {
5758 DeclStmt *BeginStmt = RangeFor->getBeginStmt();
5760 LUVDecl = RangeFor->getLoopVariable();
5762 Cond = RangeFor->getCond();
5763 Inc = RangeFor->getInc();
5765 llvm_unreachable(
"unhandled kind of loop");
5774 if (
auto *CondBinExpr = dyn_cast<BinaryOperator>(
Cond)) {
5775 LHS = CondBinExpr->getLHS();
5776 RHS = CondBinExpr->getRHS();
5777 CondRel = CondBinExpr->getOpcode();
5778 }
else if (
auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(
Cond)) {
5779 assert(CondCXXOp->getNumArgs() == 2 &&
"Comparison should have 2 operands");
5780 LHS = CondCXXOp->getArg(0);
5781 RHS = CondCXXOp->getArg(1);
5782 switch (CondCXXOp->getOperator()) {
5783 case OO_ExclaimEqual:
5795 case OO_GreaterEqual:
5799 llvm_unreachable(
"unexpected iterator operator");
5802 llvm_unreachable(
"unexpected loop condition");
5806 cast<DeclRefExpr>(LHS->
IgnoreImplicit())->getDecl() != LIVDecl) {
5807 std::swap(LHS, RHS);
5824 if (
auto *IncUn = dyn_cast<UnaryOperator>(Inc)) {
5826 switch (IncUn->getOpcode()) {
5836 llvm_unreachable(
"unhandled unary increment operator");
5839 Ctx, llvm::APInt(Ctx.
getIntWidth(LogicalTy), Direction), LogicalTy, {});
5840 }
else if (
auto *IncBin = dyn_cast<BinaryOperator>(Inc)) {
5841 if (IncBin->getOpcode() == BO_AddAssign) {
5842 Step = IncBin->getRHS();
5843 }
else if (IncBin->getOpcode() == BO_SubAssign) {
5845 AssertSuccess(BuildUnaryOp(
nullptr, {}, UO_Minus, IncBin->getRHS()));
5847 llvm_unreachable(
"unhandled binary increment operator");
5848 }
else if (
auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Inc)) {
5849 switch (CondCXXOp->getOperator()) {
5852 Ctx, llvm::APInt(Ctx.
getIntWidth(LogicalTy), 1), LogicalTy, {});
5856 Ctx, llvm::APInt(Ctx.
getIntWidth(LogicalTy), -1), LogicalTy, {});
5859 Step = CondCXXOp->getArg(1);
5863 BuildUnaryOp(
nullptr, {}, UO_Minus, CondCXXOp->getArg(1)));
5866 llvm_unreachable(
"unhandled overloaded increment operator");
5869 llvm_unreachable(
"unknown increment expression");
5874 *
this, LVTy, LogicalTy, CounterRef, Step, isa<CXXForRangeStmt>(AStmt));
5876 {},
nullptr,
nullptr, {},
nullptr);
5877 return OMPCanonicalLoop::create(getASTContext(), AStmt, DistanceFunc,
5878 LoopVarFunc, LVRef);
5883 if (isa<ForStmt>(AStmt) || isa<CXXForRangeStmt>(AStmt))
5884 return ActOnOpenMPCanonicalLoop(AStmt);
5890 "Loop transformation directive expected");
5891 return LoopTransform;
5898 Expr *UnresolvedMapper);
5910 for (
int Cnt = 0, EndCnt = Clauses.size(); Cnt < EndCnt; ++Cnt) {
5911 auto *
C = dyn_cast<OMPMapClause>(Clauses[Cnt]);
5915 auto *MI =
C->mapperlist_begin();
5916 for (
auto I =
C->varlist_begin(), End =
C->varlist_end(); I != End;
5935 if (
const auto *ATy = BaseType->getAsArrayTypeUnsafe())
5936 ElemType = ATy->getElementType();
5939 CanonType = ElemType;
5944 1, {CanonType,
nullptr});
5945 llvm::DenseMap<const Type *, Expr *> Visited;
5948 while (!Types.empty()) {
5951 std::tie(BaseType, CurFD) = Types.pop_back_val();
5952 while (ParentChain.back().second == 0)
5953 ParentChain.pop_back();
5954 --ParentChain.back().second;
5955 if (BaseType.isNull())
5958 const RecordDecl *RD = BaseType.getCanonicalType()->getAsRecordDecl();
5961 auto It = Visited.find(BaseType.getTypePtr());
5962 if (It == Visited.end()) {
5970 S, Stack->getCurScope(), MapperIdScopeSpec, DefaultMapperId,
5974 It = Visited.try_emplace(BaseType.getTypePtr(), ER.
get()).first;
5981 Expr *BaseExpr = OE;
5982 for (
const auto &
P : ParentChain) {
6000 SubExprs.push_back(BaseExpr);
6004 bool FirstIter =
true;
6014 ParentChain.emplace_back(CurFD, 1);
6016 ++ParentChain.back().second;
6018 Types.emplace_back(FieldTy, FD);
6022 if (SubExprs.empty())
6027 C->getMapTypeModifiers(),
C->getMapTypeModifiersLoc(),
6028 MapperIdScopeSpec, MapperId,
C->getMapType(),
6031 Clauses.push_back(NewClause);
6042 OMPExecutableDirective::getSingleClause<OMPBindClause>(Clauses))
6043 BindKind = BC->getBindKind();
6047 BindKind, StartLoc))
6052 bool ErrorFound =
false;
6053 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
6054 if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic &&
6055 Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master &&
6057 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
6060 DSAAttrChecker DSAChecker(
DSAStack, *
this, cast<CapturedStmt>(AStmt));
6061 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
6063 while (--ThisCaptureLevel >= 0)
6065 DSAChecker.Visit(S);
6073 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
6075 DSAChecker.visitSubCaptures(CS);
6077 if (DSAChecker.isErrorFound())
6080 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
6083 DSAChecker.getImplicitFirstprivate().begin(),
6084 DSAChecker.getImplicitFirstprivate().end());
6086 DSAChecker.getImplicitPrivate().begin(),
6087 DSAChecker.getImplicitPrivate().end());
6088 const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
6091 ImplicitMapModifiers[DefaultmapKindNum];
6093 ImplicitMapModifiersLoc[DefaultmapKindNum];
6097 if (
auto *DMC = dyn_cast<OMPDefaultmapClause>(
C))
6098 if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present)
6099 PresentModifierLocs[DMC->getDefaultmapKind()] =
6100 DMC->getDefaultmapModifierLoc();
6102 for (
unsigned VC = 0; VC < DefaultmapKindNum; ++VC) {
6104 for (
unsigned I = 0; I < OMPC_MAP_delete; ++I) {
6107 ImplicitMaps[VC][I].append(ImplicitMap.begin(), ImplicitMap.end());
6110 DSAChecker.getImplicitMapModifier(Kind);
6111 ImplicitMapModifiers[VC].append(ImplicitModifier.begin(),
6112 ImplicitModifier.end());
6113 std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[VC]),
6114 ImplicitModifier.size(), PresentModifierLocs[VC]);
6118 if (
auto *IRC = dyn_cast<OMPInReductionClause>(
C)) {
6119 for (
Expr *E : IRC->taskgroup_descriptors())
6121 ImplicitFirstprivates.emplace_back(E);
6126 if (
auto *DC = dyn_cast<OMPDetachClause>(
C))
6127 ImplicitFirstprivates.push_back(DC->getEventHandler());
6129 if (!ImplicitFirstprivates.empty()) {
6130 if (
OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
6133 ClausesWithImplicit.push_back(Implicit);
6135 ImplicitFirstprivates.size();
6140 if (!ImplicitPrivates.empty()) {
6144 ClausesWithImplicit.push_back(Implicit);
6146 ImplicitPrivates.size();
6155 if (getLangOpts().OpenMP >= 50 && Kind != OMPD_target &&
6159 if (
auto *RC = dyn_cast<OMPReductionClause>(
C))
6160 for (
Expr *E : RC->varlists())
6162 ImplicitExprs.emplace_back(E);
6164 if (!ImplicitExprs.empty()) {
6168 if (
OMPClause *Implicit = ActOnOpenMPMapClause(
6170 MapperId, OMPC_MAP_tofrom,
6173 ClausesWithImplicit.emplace_back(Implicit);
6176 for (
unsigned I = 0, E = DefaultmapKindNum; I < E; ++I) {
6177 int ClauseKindCnt = -1;
6180 if (ImplicitMap.empty())
6185 if (
OMPClause *Implicit = ActOnOpenMPMapClause(
6186 ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I],
6187 MapperIdScopeSpec, MapperId, Kind,
true,
6190 ClausesWithImplicit.emplace_back(Implicit);
6200 if (LangOpts.OpenMP >= 50)
6202 ClausesWithImplicit);
6208 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
6210 AllowedNameModifiers.push_back(OMPD_parallel);
6213 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
6214 VarsWithInheritedDSA);
6215 if (LangOpts.OpenMP >= 50)
6216 AllowedNameModifiers.push_back(OMPD_simd);
6220 ActOnOpenMPTileDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6223 Res = ActOnOpenMPUnrollDirective(ClausesWithImplicit, AStmt, StartLoc,
6227 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
6228 VarsWithInheritedDSA);
6231 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6232 EndLoc, VarsWithInheritedDSA);
6233 if (LangOpts.OpenMP >= 50)
6234 AllowedNameModifiers.push_back(OMPD_simd);
6237 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
6241 assert(ClausesWithImplicit.empty() &&
6242 "No clauses are allowed for 'omp section' directive");
6243 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
6246 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
6250 assert(ClausesWithImplicit.empty() &&
6251 "No clauses are allowed for 'omp master' directive");
6252 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
6255 Res = ActOnOpenMPMaskedDirective(ClausesWithImplicit, AStmt, StartLoc,
6259 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
6262 case OMPD_parallel_for:
6263 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
6264 EndLoc, VarsWithInheritedDSA);
6265 AllowedNameModifiers.push_back(OMPD_parallel);
6267 case OMPD_parallel_for_simd:
6268 Res = ActOnOpenMPParallelForSimdDirective(
6269 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6270 AllowedNameModifiers.push_back(OMPD_parallel);
6271 if (LangOpts.OpenMP >= 50)
6272 AllowedNameModifiers.push_back(OMPD_simd);
6274 case OMPD_parallel_master:
6275 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
6277 AllowedNameModifiers.push_back(OMPD_parallel);
6279 case OMPD_parallel_masked:
6280 Res = ActOnOpenMPParallelMaskedDirective(ClausesWithImplicit, AStmt,
6282 AllowedNameModifiers.push_back(OMPD_parallel);
6284 case OMPD_parallel_sections:
6285 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
6287 AllowedNameModifiers.push_back(OMPD_parallel);
6291 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6292 AllowedNameModifiers.push_back(OMPD_task);
6294 case OMPD_taskyield:
6295 assert(ClausesWithImplicit.empty() &&
6296 "No clauses are allowed for 'omp taskyield' directive");
6297 assert(AStmt ==
nullptr &&
6298 "No associated statement allowed for 'omp taskyield' directive");
6299 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
6302 assert(ClausesWithImplicit.empty() &&
6303 "No clauses are allowed for 'omp barrier' directive");
6304 assert(AStmt ==
nullptr &&
6305 "No associated statement allowed for 'omp barrier' directive");
6306 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
6309 assert(AStmt ==
nullptr &&
6310 "No associated statement allowed for 'omp taskwait' directive");
6311 Res = ActOnOpenMPTaskwaitDirective(ClausesWithImplicit, StartLoc, EndLoc);
6313 case OMPD_taskgroup:
6314 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
6318 assert(AStmt ==
nullptr &&
6319 "No associated statement allowed for 'omp flush' directive");
6320 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
6323 assert(AStmt ==
nullptr &&
6324 "No associated statement allowed for 'omp depobj' directive");
6325 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc);
6328 assert(AStmt ==
nullptr &&
6329 "No associated statement allowed for 'omp scan' directive");
6330 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc);
6333 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
6337 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
6342 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6345 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
6347 AllowedNameModifiers.push_back(OMPD_target);
6349 case OMPD_target_parallel:
6350 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
6352 AllowedNameModifiers.push_back(OMPD_target);
6353 AllowedNameModifiers.push_back(OMPD_parallel);
6355 case OMPD_target_parallel_for:
6356 Res = ActOnOpenMPTargetParallelForDirective(
6357 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6358 AllowedNameModifiers.push_back(OMPD_target);
6359 AllowedNameModifiers.push_back(OMPD_parallel);
6361 case OMPD_cancellation_point:
6362 assert(ClausesWithImplicit.empty() &&
6363 "No clauses are allowed for 'omp cancellation point' directive");
6364 assert(AStmt ==
nullptr &&
"No associated statement allowed for 'omp "
6365 "cancellation point' directive");
6366 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
6369 assert(AStmt ==
nullptr &&
6370 "No associated statement allowed for 'omp cancel' directive");
6371 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
6373 AllowedNameModifiers.push_back(OMPD_cancel);
6375 case OMPD_target_data:
6376 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
6378 AllowedNameModifiers.push_back(OMPD_target_data);
6380 case OMPD_target_enter_data:
6381 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
6383 AllowedNameModifiers.push_back(OMPD_target_enter_data);
6385 case OMPD_target_exit_data:
6386 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
6388 AllowedNameModifiers.push_back(OMPD_target_exit_data);
6391 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
6392 EndLoc, VarsWithInheritedDSA);
6393 AllowedNameModifiers.push_back(OMPD_taskloop);
6395 case OMPD_taskloop_simd:
6396 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6397 EndLoc, VarsWithInheritedDSA);
6398 AllowedNameModifiers.push_back(OMPD_taskloop);
6399 if (LangOpts.OpenMP >= 50)
6400 AllowedNameModifiers.push_back(OMPD_simd);
6402 case OMPD_master_taskloop:
6403 Res = ActOnOpenMPMasterTaskLoopDirective(
6404 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6405 AllowedNameModifiers.push_back(OMPD_taskloop);
6407 case OMPD_masked_taskloop:
6408 Res = ActOnOpenMPMaskedTaskLoopDirective(
6409 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6410 AllowedNameModifiers.push_back(OMPD_taskloop);
6412 case OMPD_master_taskloop_simd:
6413 Res = ActOnOpenMPMasterTaskLoopSimdDirective(
6414 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6415 AllowedNameModifiers.push_back(OMPD_taskloop);
6416 if (LangOpts.OpenMP >= 50)
6417 AllowedNameModifiers.push_back(OMPD_simd);
6419 case OMPD_masked_taskloop_simd:
6420 Res = ActOnOpenMPMaskedTaskLoopSimdDirective(
6421 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6422 if (LangOpts.OpenMP >= 51) {
6423 AllowedNameModifiers.push_back(OMPD_taskloop);
6424 AllowedNameModifiers.push_back(OMPD_simd);
6427 case OMPD_parallel_master_taskloop:
6428 Res = ActOnOpenMPParallelMasterTaskLoopDirective(
6429 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6430 AllowedNameModifiers.push_back(OMPD_taskloop);
6431 AllowedNameModifiers.push_back(OMPD_parallel);
6433 case OMPD_parallel_masked_taskloop:
6434 Res = ActOnOpenMPParallelMaskedTaskLoopDirective(
6435 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6436 if (LangOpts.OpenMP >= 51) {
6437 AllowedNameModifiers.push_back(OMPD_taskloop);
6438 AllowedNameModifiers.push_back(OMPD_parallel);
6441 case OMPD_parallel_master_taskloop_simd:
6442 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective(
6443 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6444 AllowedNameModifiers.push_back(OMPD_taskloop);
6445 AllowedNameModifiers.push_back(OMPD_parallel);
6446 if (LangOpts.OpenMP >= 50)
6447 AllowedNameModifiers.push_back(OMPD_simd);
6449 case OMPD_parallel_masked_taskloop_simd:
6450 Res = ActOnOpenMPParallelMaskedTaskLoopSimdDirective(
6451 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6452 if (LangOpts.OpenMP >= 51) {
6453 AllowedNameModifiers.push_back(OMPD_taskloop);
6454 AllowedNameModifiers.push_back(OMPD_parallel);
6455 AllowedNameModifiers.push_back(OMPD_simd);
6458 case OMPD_distribute:
6459 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
6460 EndLoc, VarsWithInheritedDSA);
6462 case OMPD_target_update:
6463 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
6465 AllowedNameModifiers.push_back(OMPD_target_update);
6467 case OMPD_distribute_parallel_for:
6468 Res = ActOnOpenMPDistributeParallelForDirective(
6469 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6470 AllowedNameModifiers.push_back(OMPD_parallel);
6472 case OMPD_distribute_parallel_for_simd:
6473 Res = ActOnOpenMPDistributeParallelForSimdDirective(
6474 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6475 AllowedNameModifiers.push_back(OMPD_parallel);
6476 if (LangOpts.OpenMP >= 50)
6477 AllowedNameModifiers.push_back(OMPD_simd);
6479 case OMPD_distribute_simd:
6480 Res = ActOnOpenMPDistributeSimdDirective(
6481 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6482 if (LangOpts.OpenMP >= 50)
6483 AllowedNameModifiers.push_back(OMPD_simd);
6485 case OMPD_target_parallel_for_simd:
6486 Res = ActOnOpenMPTargetParallelForSimdDirective(
6487 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6488 AllowedNameModifiers.push_back(OMPD_target);
6489 AllowedNameModifiers.push_back(OMPD_parallel);
6490 if (LangOpts.OpenMP >= 50)
6491 AllowedNameModifiers.push_back(OMPD_simd);
6493 case OMPD_target_simd:
6494 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6495 EndLoc, VarsWithInheritedDSA);
6496 AllowedNameModifiers.push_back(OMPD_target);
6497 if (LangOpts.OpenMP >= 50)
6498 AllowedNameModifiers.push_back(OMPD_simd);
6500 case OMPD_teams_distribute:
6501 Res = ActOnOpenMPTeamsDistributeDirective(
6502 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6504 case OMPD_teams_distribute_simd:
6505 Res = ActOnOpenMPTeamsDistributeSimdDirective(
6506 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6507 if (LangOpts.OpenMP >= 50)
6508 AllowedNameModifiers.push_back(OMPD_simd);
6510 case OMPD_teams_distribute_parallel_for_simd:
6511 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
6512 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6513 AllowedNameModifiers.push_back(OMPD_parallel);
6514 if (LangOpts.OpenMP >= 50)
6515 AllowedNameModifiers.push_back(OMPD_simd);
6517 case OMPD_teams_distribute_parallel_for:
6518 Res = ActOnOpenMPTeamsDistributeParallelForDirective(
6519 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6520 AllowedNameModifiers.push_back(OMPD_parallel);
6522 case OMPD_target_teams:
6523 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
6525 AllowedNameModifiers.push_back(OMPD_target);
6527 case OMPD_target_teams_distribute:
6528 Res = ActOnOpenMPTargetTeamsDistributeDirective(
6529 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6530 AllowedNameModifiers.push_back(OMPD_target);
6532 case OMPD_target_teams_distribute_parallel_for:
6533 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
6534 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6535 AllowedNameModifiers.push_back(OMPD_target);
6536 AllowedNameModifiers.push_back(OMPD_parallel);
6538 case OMPD_target_teams_distribute_parallel_for_simd:
6539 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
6540 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6541 AllowedNameModifiers.push_back(OMPD_target);
6542 AllowedNameModifiers.push_back(OMPD_parallel);
6543 if (LangOpts.OpenMP >= 50)
6544 AllowedNameModifiers.push_back(OMPD_simd);
6546 case OMPD_target_teams_distribute_simd:
6547 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
6548 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6549 AllowedNameModifiers.push_back(OMPD_target);
6550 if (LangOpts.OpenMP >= 50)
6551 AllowedNameModifiers.push_back(OMPD_simd);
6554 assert(AStmt ==
nullptr &&
6555 "No associated statement allowed for 'omp interop' directive");
6556 Res = ActOnOpenMPInteropDirective(ClausesWithImplicit, StartLoc, EndLoc);
6559 Res = ActOnOpenMPDispatchDirective(ClausesWithImplicit, AStmt, StartLoc,
6563 Res = ActOnOpenMPGenericLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
6564 EndLoc, VarsWithInheritedDSA);
6566 case OMPD_teams_loop:
6567 Res = ActOnOpenMPTeamsGenericLoopDirective(
6568 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6570 case OMPD_target_teams_loop:
6571 Res = ActOnOpenMPTargetTeamsGenericLoopDirective(
6572 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6574 case OMPD_parallel_loop:
6575 Res = ActOnOpenMPParallelGenericLoopDirective(
6576 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6578 case OMPD_target_parallel_loop:
6579 Res = ActOnOpenMPTargetParallelGenericLoopDirective(
6580 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6582 case OMPD_declare_target:
6583 case OMPD_end_declare_target:
6584 case OMPD_threadprivate:
6586 case OMPD_declare_reduction:
6587 case OMPD_declare_mapper:
6588 case OMPD_declare_simd:
6590 case OMPD_declare_variant:
6591 case OMPD_begin_declare_variant:
6592 case OMPD_end_declare_variant:
6593 llvm_unreachable(
"OpenMP Directive is not allowed");
6596 llvm_unreachable(
"Unknown OpenMP directive");
6599 ErrorFound = Res.
isInvalid() || ErrorFound;
6603 if (
DSAStack->getDefaultDSA() == DSA_none ||
6604 DSAStack->getDefaultDSA() == DSA_private ||
6605 DSAStack->getDefaultDSA() == DSA_firstprivate) {
6606 DSAAttrChecker DSAChecker(
DSAStack, *
this,
nullptr);
6608 switch (
C->getClauseKind()) {
6609 case OMPC_num_threads:
6610 case OMPC_dist_schedule:
6617 cast<OMPIfClause>(
C)->getNameModifier() != OMPD_target)
6621 cast<OMPIfClause>(
C)->getNameModifier() != OMPD_parallel)
6627 case OMPC_grainsize:
6628 case OMPC_num_tasks:
6631 case OMPC_novariants:
6632 case OMPC_nocontext:
6639 case OMPC_num_teams:
6640 case OMPC_thread_limit:
6647 case OMPC_proc_bind:
6649 case OMPC_firstprivate:
6650 case OMPC_lastprivate:
6652 case OMPC_reduction:
6653 case OMPC_task_reduction:
6654 case OMPC_in_reduction:
6658 case OMPC_copyprivate:
6661 case OMPC_mergeable:
6678 case OMPC_defaultmap:
6681 case OMPC_use_device_ptr:
6682 case OMPC_use_device_addr:
6683 case OMPC_is_device_ptr:
6684 case OMPC_has_device_addr:
6685 case OMPC_nontemporal:
6688 case OMPC_inclusive:
6689 case OMPC_exclusive:
6690 case OMPC_uses_allocators:
6695 case OMPC_allocator:
6698 case OMPC_threadprivate:
6701 case OMPC_unified_address:
6702 case OMPC_unified_shared_memory:
6703 case OMPC_reverse_offload:
6704 case OMPC_dynamic_allocators:
6705 case OMPC_atomic_default_mem_order:
6706 case OMPC_device_type:
6710 llvm_unreachable(
"Unexpected clause");
6714 DSAChecker.Visit(CC);
6717 for (
const auto &
P : DSAChecker.getVarsWithInheritedDSA())
6718 VarsWithInheritedDSA[
P.getFirst()] =
P.getSecond();
6720 for (
const auto &
P : VarsWithInheritedDSA) {
6721 if (
P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(
P.getFirst()))
6724 if (
DSAStack->getDefaultDSA() == DSA_none ||
6725 DSAStack->getDefaultDSA() == DSA_private ||
6726 DSAStack->getDefaultDSA() == DSA_firstprivate) {
6727 Diag(
P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
6728 <<
P.first <<
P.second->getSourceRange();
6729 Diag(
DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
6730 }
else if (getLangOpts().OpenMP >= 50) {
6731 Diag(
P.second->getExprLoc(),
6732 diag::err_omp_defaultmap_no_attr_for_variable)
6733 <<
P.first <<
P.second->getSourceRange();
6735 diag::note_omp_defaultmap_attr_none);
6739 if (!AllowedNameModifiers.empty())
6740 ErrorFound =
checkIfClauses(*
this, Kind, Clauses, AllowedNameModifiers) ||
6746 if (!CurContext->isDependentContext() &&
6753 DSAStack->addTargetDirLocation(StartLoc);
6764 assert(Aligneds.size() == Alignments.size());
6765 assert(Linears.size() == LinModifiers.size());
6766 assert(Linears.size() == Steps.size());
6767 if (!DG || DG.
get().isNull())
6770 const int SimdId = 0;
6771 if (!DG.
get().isSingleDecl()) {
6772 Diag(SR.
getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
6776 Decl *ADecl = DG.
get().getSingleDecl();
6777 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
6778 ADecl = FTD->getTemplatedDecl();
6780 auto *FD = dyn_cast<FunctionDecl>(ADecl);
6782 Diag(ADecl->
getLocation(), diag::err_omp_function_expected) << SimdId;
6791 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
6798 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
6799 const Expr *UniformedLinearThis =
nullptr;
6800 for (
const Expr *E : Uniforms) {
6802 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
6803 if (
const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
6804 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6805 FD->getParamDecl(PVD->getFunctionScopeIndex())
6807 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
6810 if (isa<CXXThisExpr>(E)) {
6811 UniformedLinearThis = E;
6825 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
6826 const Expr *AlignedThis =
nullptr;
6827 for (
const Expr *E : Aligneds) {
6829 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
6830 if (
const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6832 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6833 FD->getParamDecl(PVD->getFunctionScopeIndex())
6837 if (AlignedArgs.count(CanonPVD) > 0) {
6839 << 1 << getOpenMPClauseName(OMPC_aligned)
6841 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
6842 diag::note_omp_explicit_dsa)
6843 << getOpenMPClauseName(OMPC_aligned);
6846 AlignedArgs[CanonPVD] = E;
6848 .getNonReferenceType()
6849 .getUnqualifiedType()
6850 .getCanonicalType();
6853 Diag(E->
getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
6855 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
6860 if (isa<CXXThisExpr>(E)) {
6863 << 2 << getOpenMPClauseName(OMPC_aligned) << E->
getSourceRange();
6865 << getOpenMPClauseName(OMPC_aligned);
6878 for (
Expr *E : Alignments) {
6881 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
6882 NewAligns.push_back(Align.
get());
6893 llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
6894 const bool IsUniformedThis = UniformedLinearThis !=
nullptr;
6895 auto MI = LinModifiers.begin();
6896 for (
const Expr *E : Linears) {
6900 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
6901 if (
const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6903 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6904 FD->getParamDecl(PVD->getFunctionScopeIndex())
6908 if (LinearArgs.count(CanonPVD) > 0) {
6910 << getOpenMPClauseName(OMPC_linear)
6912 Diag(LinearArgs[CanonPVD]->getExprLoc(),
6913 diag::note_omp_explicit_dsa)
6914 << getOpenMPClauseName(OMPC_linear);
6918 if (UniformedArgs.count(CanonPVD) > 0) {
6920 << getOpenMPClauseName(OMPC_linear)
6922 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
6923 diag::note_omp_explicit_dsa)
6924 << getOpenMPClauseName(OMPC_uniform);
6927 LinearArgs[CanonPVD] = E;
6932 (void)CheckOpenMPLinearDecl(CanonPVD, E->
getExprLoc(), LinKind,
6933 PVD->getOriginalType(),
6938 if (isa<CXXThisExpr>(E)) {
6939 if (UniformedLinearThis) {
6941 << getOpenMPClauseName(OMPC_linear)
6942 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
6944 Diag(UniformedLinearThis->
getExprLoc(), diag::note_omp_explicit_dsa)
6945 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
6949 UniformedLinearThis = E;
6953 (void)CheckOpenMPLinearDecl(
nullptr, E->
getExprLoc(), LinKind,
6960 Expr *Step =
nullptr;
6961 Expr *NewStep =
nullptr;
6963 for (
Expr *E : Steps) {
6965 if (Step == E || !E) {
6966 NewSteps.push_back(E ? NewStep :
nullptr);
6970 if (
const auto *DRE = dyn_cast<DeclRefExpr>(Step))
6971 if (
const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6973 if (UniformedArgs.count(CanonPVD) == 0) {
6980 NewSteps.push_back(Step);
6991 NewStep = PerformOpenMPImplicitIntegerConversion(Step->
getExprLoc(), Step)
6995 VerifyIntegerConstantExpression(NewStep, AllowFold).get();
6997 NewSteps.push_back(NewStep);
6999 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
7000 Context, BS, SL.
get(),
const_cast<Expr **
>(Uniforms.data()),
7001 Uniforms.size(),
const_cast<Expr **
>(Aligneds.data()), Aligneds.size(),
7002 const_cast<Expr **
>(NewAligns.data()), NewAligns.size(),
7003 const_cast<Expr **
>(Linears.data()), Linears.size(),
7004 const_cast<unsigned *
>(LinModifiers.data()), LinModifiers.size(),
7005 NewSteps.data(), NewSteps.size(), SR);
7013 "Expected function type with prototype.");
7015 "Expected function with type with no prototype.");
7017 "Expected function with prototype.");
7025 Param->setScopeInfo(0, Params.size());
7026 Param->setImplicit();
7027 Params.push_back(Param);
7030 FD->setParams(Params);
7037 if (
auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
7038 FD = UTemplDecl->getTemplatedDecl();
7041 assert(FD &&
"Expected a function declaration!");
7046 if (!inTemplateInstantiation()) {
7047 for (AssumptionAttr *AA : OMPAssumeScoped)
7050 for (AssumptionAttr *AA : OMPAssumeGlobal)
7054Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(
OMPTraitInfo &TI)
7055 : TI(&TI), NameSuffix(TI.getMangledName()) {}
7063 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
7066 bool IsTemplated = !TemplateParamLists.empty();
7069 llvm::omp::TraitProperty::implementation_extension_allow_templates))
7085 for (
auto *Candidate : Lookup) {
7086 auto *CandidateDecl = Candidate->getUnderlyingDecl();
7088 if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl)) {
7090 if (FTD->getTemplateParameters()->size() == TemplateParamLists.size())
7091 UDecl = FTD->getTemplatedDecl();
7092 }
else if (!IsTemplated)
7093 UDecl = dyn_cast<FunctionDecl>(CandidateDecl);
7107 FType, UDeclTy,
false,
7114 Bases.push_back(UDecl);
7118 llvm::omp::TraitProperty::implementation_extension_disable_implicit_base);
7120 if (Bases.empty() && UseImplicitBase) {
7124 if (
auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD))
7125 Bases.push_back(BaseTemplD->getTemplatedDecl());
7127 Bases.push_back(cast<FunctionDecl>(BaseD));
7130 std::string MangledName;
7133 MangledName += DVScope.NameSuffix;
7148 if (
auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
7149 FD = UTemplDecl->getTemplatedDecl();
7158 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
7159 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit(
7160 Context, VariantFuncRef, DVScope.TI,
7165 BaseFD->addAttr(OMPDeclareVariantA);
7174 CallExpr *CE = dyn_cast<CallExpr>(Call.get());
7182 if (!CalleeFnDecl->
hasAttr<OMPDeclareVariantAttr>())
7186 std::function<void(StringRef)> DiagUnknownTrait = [
this,
7187 CE](StringRef ISATrait) {
7200 while (CalleeFnDecl) {
7201 for (OMPDeclareVariantAttr *A :
7203 Expr *VariantRef = A->getVariantFuncRef();
7205 VariantMatchInfo VMI;
7208 if (!isVariantApplicableInContext(VMI, OMPCtx,
7212 VMIs.push_back(VMI);
7213 Exprs.push_back(VariantRef);
7221 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
7241 if (
auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) {
7242 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE);
7244 Context, MemberCall->getImplicitObjectArgument(),
7246 MemberCall->getValueKind(), MemberCall->getObjectKind());
7251 if (
CallExpr *NCE = dyn_cast<CallExpr>(NewCall.
get())) {
7252 FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee();
7254 CalleeFnType, NewCalleeFnDecl->
getType(),
7265 VMIs.erase(VMIs.begin() + BestIdx);
7266 Exprs.erase(Exprs.begin() + BestIdx);
7267 }
while (!VMIs.empty());
7277 unsigned NumAppendArgs,
7279 if (!DG || DG.
get().isNull())
7282 const int VariantId = 1;
7284 if (!DG.
get().isSingleDecl()) {
7285 Diag(SR.
getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
7289 Decl *ADecl = DG.
get().getSingleDecl();
7290 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
7291 ADecl = FTD->getTemplatedDecl();
7294 auto *FD = dyn_cast<FunctionDecl>(ADecl);
7301 auto &&HasMultiVersionAttributes = [](
const FunctionDecl *FD) {
7304 return FD->isMultiVersion() || FD->
hasAttr<TargetAttr>();
7307 if (HasMultiVersionAttributes(FD)) {
7308 Diag(FD->
getLocation(), diag::err_omp_declare_variant_incompat_attributes)
7315 Diag(SR.
getBegin(), diag::warn_omp_declare_variant_after_used)
7320 if (!FD->isThisDeclarationADefinition() && FD->isDefined(
Definition) &&
7322 Diag(SR.
getBegin(), diag::warn_omp_declare_variant_after_emitted)
7327 Diag(SR.
getBegin(), diag::err_omp_function_expected) << VariantId;
7331 auto ShouldDelayChecks = [](
Expr *&E,
bool) {
7337 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef,
false) ||
7339 return std::make_pair(FD, VariantRef);
7342 auto HandleNonConstantScoresAndConditions = [
this](
Expr *&E,
7343 bool IsScore) ->
bool {
7349 Diag(E->
getExprLoc(), diag::warn_omp_declare_variant_score_not_constant)
7357 diag::err_omp_declare_variant_user_condition_not_constant)
7366 if (NumAppendArgs) {
7369 Diag(FD->
getLocation(), diag::err_omp_declare_variant_prototype_required)
7380 TD = dyn_cast_or_null<TypeDecl>(ND);
7383 Diag(SR.
getBegin(), diag::err_omp_interop_type_not_found) << SR;
7387 if (PTy->isVariadic()) {
7388 Diag(FD->
getLocation(), diag::err_omp_append_args_with_varargs) << SR;
7392 Params.append(PTy->param_type_begin(), PTy->param_type_end());
7393 Params.insert(Params.end(), NumAppendArgs, InteropType);
7395 PTy->getExtProtoInfo());
7403 auto *Method = dyn_cast<CXXMethodDecl>(FD);
7404 if (Method && !Method->isStatic()) {
7405 const Type *ClassType =
7421 VariantRef = ER.
get();
7429 false, AllowedExplicit::None,
7435 diag::err_omp_declare_variant_incompat_types)
7437 << ((Method && !Method->isStatic()) ? FnPtrType : FD->
getType())
7447 if (Method && !Method->isStatic()) {
7448 Expr *PossibleAddrOfVariantRef = VariantRefCast.
get();
7449 if (
auto *UO = dyn_cast<UnaryOperator>(
7451 VariantRefCast = UO->getSubExpr();
7470 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
7479 diag::err_omp_declare_variant_same_base_function)
7490 diag::err_omp_declare_variant_incompat_types)
7491 << NewFD->getType() << FD->
getType() << (NumAppendArgs ? 1 : 0)
7498 else if (NewFD->getType()->isFunctionNoProtoType())
7504 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
7506 diag::warn_omp_declare_variant_marked_as_declare_variant)
7509 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
7510 Diag(SR.
getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
7514 enum DoesntSupport {
7523 if (
const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
7524 if (CXXFD->isVirtual()) {
7530 if (isa<CXXConstructorDecl>(FD)) {
7536 if (isa<CXXDestructorDecl>(FD)) {
7543 if (FD->isDeleted()) {
7549 if (FD->isDefaulted()) {
7555 if (FD->isConstexpr()) {
7557 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
7568 PDiag(diag::err_omp_declare_variant_doesnt_support)),
7570 PDiag(diag::err_omp_declare_variant_diff)
7575 return std::make_pair(FD, cast<Expr>(DRE));
7592 llvm::append_range(AllAdjustArgs, AdjustArgsNothing);
7593 llvm::append_range(AllAdjustArgs, AdjustArgsNeedDevicePtr);
7595 if (!AllAdjustArgs.empty() || !AppendArgs.empty()) {
7596 VariantMatchInfo VMI;
7598 if (!llvm::is_contained(
7599 VMI.ConstructTraits,
7600 llvm::omp::TraitProperty::construct_dispatch_dispatch)) {
7601 if (!AllAdjustArgs.empty())
7602 Diag(AdjustArgsLoc, diag::err_omp_clause_requires_dispatch_construct)
7603 << getOpenMPClauseName(OMPC_adjust_args);
7604 if (!AppendArgs.empty())
7605 Diag(AppendArgsLoc, diag::err_omp_clause_requires_dispatch_construct)
7606 << getOpenMPClauseName(OMPC_append_args);
7616 for (
Expr *E : AllAdjustArgs) {
7618 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
7619 if (
const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7621 if (FD->
getNumParams() > PVD->getFunctionScopeIndex() &&
7625 if (!AdjustVars.insert(CanonPVD).second) {
7626 Diag(DRE->getLocation(), diag::err_omp_adjust_arg_multiple_clauses)
7635 Diag(E->
getExprLoc(), diag::err_omp_param_or_this_in_clause) << FD << 0;
7639 auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit(
7640 Context, VariantRef, &TI,
const_cast<Expr **
>(AdjustArgsNothing.data()),
7641 AdjustArgsNothing.size(),
7642 const_cast<Expr **
>(AdjustArgsNeedDevicePtr.data()),
7643 AdjustArgsNeedDevicePtr.size(),
7644 const_cast<OMPDeclareVariantAttr::InteropType *
>(AppendArgs.data()),
7645 AppendArgs.size(), SR);
7666 return OMPParallelDirective::Create(
Context, StartLoc, EndLoc, Clauses, AStmt,
7667 DSAStack->getTaskgroupReductionRef(),
7673struct LoopIterationSpace final {
7676 bool IsStrictCompare =
false;
7678 Expr *PreCond =
nullptr;
7681 Expr *NumIterations =
nullptr;
7683 Expr *CounterVar =
nullptr;
7685 Expr *PrivateCounterVar =
nullptr;
7687 Expr *CounterInit =
nullptr;
7690 Expr *CounterStep =
nullptr;
7692 bool Subtract =
false;
7702 Expr *MinValue =
nullptr;
7706 Expr *MaxValue =
nullptr;
7708 bool IsNonRectangularLB =
false;
7710 bool IsNonRectangularUB =
false;
7713 unsigned LoopDependentIdx = 0;
7717 Expr *FinalCondition =
nullptr;
7723class OpenMPIterationSpaceChecker {
7727 bool SupportsNonRectangular;
7743 Expr *LCRef =
nullptr;
7749 Expr *Step =
nullptr;
7758 bool TestIsStrictOp =
false;
7760 bool SubtractStep =
false;
7776 OpenMPIterationSpaceChecker(
Sema &SemaRef,
bool SupportsNonRectangular,
7778 : SemaRef(SemaRef), SupportsNonRectangular(SupportsNonRectangular),
7779 Stack(Stack), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
7782 bool checkAndSetInit(
Stmt *S,
bool EmitDiags =
true);
7785 bool checkAndSetCond(
Expr *S);
7788 bool checkAndSetInc(
Expr *S);
7790 ValueDecl *getLoopDecl()
const {
return LCDecl; }
7792 Expr *getLoopDeclRefExpr()
const {
return LCRef; }
7794 SourceRange getInitSrcRange()
const {
return InitSrcRange; }
7796 SourceRange getConditionSrcRange()
const {
return ConditionSrcRange; }
7798 SourceRange getIncrementSrcRange()
const {
return IncrementSrcRange; }
7800 bool shouldSubtractStep()
const {
return SubtractStep; }
7802 bool isStrictTestOp()
const {
return TestIsStrictOp; }
7804 Expr *buildNumIterations(
7806 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const;
7810 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const;
7813 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7814 DSAStackTy &DSA)
const;
7817 Expr *buildPrivateCounterVar()
const;
7821 Expr *buildCounterStep()
const;
7825 buildOrderedLoopData(
Scope *S,
Expr *Counter,
7826 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7830 std::pair<Expr *, Expr *> buildMinMaxValues(
7831 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const;
7833 Expr *buildFinalCondition(
Scope *S)
const;
7835 bool dependent()
const;
7837 bool doesInitDependOnLC()
const {
return InitDependOnLC.has_value(); }
7839 bool doesCondDependOnLC()
const {
return CondDependOnLC.has_value(); }
7841 unsigned getLoopDependentIdx()
const {
7842 return InitDependOnLC.value_or(CondDependOnLC.value_or(0));
7848 bool checkAndSetIncRHS(
Expr *RHS);
7856 bool setStep(
Expr *NewStep,
bool Subtract);
7859bool OpenMPIterationSpaceChecker::dependent()
const {
7861 assert(!LB && !UB && !Step);
7869bool OpenMPIterationSpaceChecker::setLCDeclAndLB(
ValueDecl *NewLCDecl,
7871 Expr *NewLB,
bool EmitDiags) {
7873 assert(LCDecl ==
nullptr && LB ==
nullptr && LCRef ==
nullptr &&
7874 UB ==
nullptr && Step ==
nullptr && !TestIsLessOp && !TestIsStrictOp);
7878 LCRef = NewLCRefExpr;
7879 if (
auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
7881 if ((Ctor->isCopyOrMoveConstructor() ||
7882 Ctor->isConvertingConstructor(
false)) &&
7883 CE->getNumArgs() > 0 && CE->getArg(0) !=
nullptr)
7887 InitDependOnLC = doesDependOnLoopCounter(LB,
true);
7891bool OpenMPIterationSpaceChecker::setUB(
Expr *NewUB,
7896 assert(LCDecl !=
nullptr && LB !=
nullptr && UB ==
nullptr &&
7897 Step ==
nullptr && !TestIsLessOp && !TestIsStrictOp);
7902 TestIsLessOp = LessOp;
7903 TestIsStrictOp = StrictOp;
7904 ConditionSrcRange = SR;
7906 CondDependOnLC = doesDependOnLoopCounter(UB,
false);
7910bool OpenMPIterationSpaceChecker::setStep(
Expr *NewStep,
bool Subtract) {
7912 assert(LCDecl !=
nullptr && LB !=
nullptr && Step ==
nullptr);
7922 NewStep = Val.
get();
7946 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
7949 (TestIsLessOp.value() ? (IsConstNeg || (IsUnsigned && Subtract))
7950 : (IsConstPos || (IsUnsigned && !Subtract))))) {
7952 diag::err_omp_loop_incr_not_compatible)
7954 SemaRef.
Diag(ConditionLoc,
7955 diag::note_omp_loop_cond_requres_compatible_incr)
7956 << TestIsLessOp.value() << ConditionSrcRange;
7959 if (TestIsLessOp.value() == Subtract) {
7963 Subtract = !Subtract;
7968 SubtractStep = Subtract;
7975class LoopCounterRefChecker final
7982 bool IsInitializer =
true;
7983 bool SupportsNonRectangular;
7984 unsigned BaseLoopId = 0;
7987 SemaRef.Diag(E->
getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
7988 << (IsInitializer ? 0 : 1);
7991 const auto &&Data = Stack.isLoopControlVariable(VD);
7997 llvm::raw_svector_ostream
OS(Name);
8001 diag::err_omp_wrong_dependency_iterator_type)
8003 SemaRef.Diag(VD->
getLocation(), diag::note_previous_decl) << VD;
8006 if (Data.first && !SupportsNonRectangular) {
8007 SemaRef.Diag(E->
getExprLoc(), diag::err_omp_invariant_dependency);
8011 (DepDecl || (PrevDepDecl &&
8013 if (!DepDecl && PrevDepDecl)
8014 DepDecl = PrevDepDecl;
8016 llvm::raw_svector_ostream
OS(Name);
8020 diag::err_omp_invariant_or_linear_dependency)
8026 BaseLoopId = Data.first;
8034 if (isa<VarDecl>(VD))
8035 return checkDecl(E, VD);
8041 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
8042 return checkDecl(E, VD);
8046 bool VisitStmt(
const Stmt *S) {
8048 for (
const Stmt *Child : S->children())
8049 Res = (Child && Visit(Child)) || Res;
8052 explicit LoopCounterRefChecker(
Sema &SemaRef, DSAStackTy &Stack,
8053 const ValueDecl *CurLCDecl,
bool IsInitializer,
8055 bool SupportsNonRectangular =
true)
8056 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
8057 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer),
8058 SupportsNonRectangular(SupportsNonRectangular) {}
8059 unsigned getBaseLoopId()
const {
8060 assert(CurLCDecl &&
"Expected loop dependency.");
8064 assert(CurLCDecl &&
"Expected loop dependency.");
8071OpenMPIterationSpaceChecker::doesDependOnLoopCounter(
const Stmt *S,
8072 bool IsInitializer) {
8074 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
8075 DepDecl, SupportsNonRectangular);
8076 if (LoopStmtChecker.Visit(S)) {
8077 DepDecl = LoopStmtChecker.getDepDecl();
8078 return LoopStmtChecker.getBaseLoopId();
8083bool OpenMPIterationSpaceChecker::checkAndSetInit(
Stmt *S,
bool EmitDiags) {
8094 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
8098 if (
auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
8099 if (!ExprTemp->cleanupsHaveSideEffects())
8100 S = ExprTemp->getSubExpr();
8102 InitSrcRange = S->getSourceRange();
8103 if (
Expr *E = dyn_cast<Expr>(S))
8105 if (
auto *BO = dyn_cast<BinaryOperator>(S)) {
8106 if (BO->getOpcode() == BO_Assign) {
8108 if (
auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
8109 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
8111 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8113 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
8115 if (
auto *ME = dyn_cast<MemberExpr>(LHS)) {
8116 if (ME->isArrow() &&
8117 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8118 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8122 }
else if (
auto *DS = dyn_cast<DeclStmt>(S)) {
8123 if (DS->isSingleDecl()) {
8124 if (
auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
8125 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
8128 SemaRef.Diag(S->getBeginLoc(),
8129 diag::ext_omp_loop_not_canonical_init)
8130 << S->getSourceRange();
8131 return setLCDeclAndLB(
8134 Var->getType().getNonReferenceType(),
8136 Var->getInit(), EmitDiags);
8140 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8141 if (CE->getOperator() == OO_Equal) {
8142 Expr *LHS = CE->getArg(0);
8143 if (
auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
8144 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
8146 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8148 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
8150 if (
auto *ME = dyn_cast<MemberExpr>(LHS)) {
8151 if (ME->isArrow() &&
8152 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8153 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8159 if (dependent() || SemaRef.CurContext->isDependentContext())
8162 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
8163 << S->getSourceRange();
8174 if (
const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
8176 if ((Ctor->isCopyOrMoveConstructor() ||
8177 Ctor->isConvertingConstructor(
false)) &&
8178 CE->getNumArgs() > 0 && CE->getArg(0) !=
nullptr)
8180 if (
const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
8181 if (
const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
8184 if (
const auto *ME = dyn_cast_or_null<MemberExpr>(E))
8185 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8190bool OpenMPIterationSpaceChecker::checkAndSetCond(
Expr *S) {
8197 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
8199 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
8200 << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
8206 auto &&CheckAndSetCond = [
this, IneqCondIsCanonical](
8211 if (getInitLCDecl(LHS) == LCDecl)
8212 return setUB(
const_cast<Expr *
>(RHS),
8213 (Opcode == BO_LT || Opcode == BO_LE),
8214 (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
8215 if (getInitLCDecl(RHS) == LCDecl)
8216 return setUB(
const_cast<Expr *
>(LHS),
8217 (Opcode == BO_GT || Opcode == BO_GE),
8218 (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
8219 }
else if (IneqCondIsCanonical && Opcode == BO_NE) {
8220 return setUB(
const_cast<Expr *
>(getInitLCDecl(LHS) == LCDecl ? RHS : LHS),
8227 if (
auto *RBO = dyn_cast<CXXRewrittenBinaryOperator>(S)) {
8230 RBO->getOperatorLoc());
8231 }
else if (
auto *BO = dyn_cast<BinaryOperator>(S)) {
8232 Res = CheckAndSetCond(BO->getOpcode(), BO->getLHS(), BO->getRHS(),
8233 BO->getSourceRange(), BO->getOperatorLoc());
8234 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8235 if (CE->getNumArgs() == 2) {
8236 Res = CheckAndSetCond(
8238 CE->getArg(1), CE->getSourceRange(), CE->getOperatorLoc());
8243 if (dependent() || SemaRef.CurContext->isDependentContext())
8245 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
8246 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl;
8250bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(
Expr *RHS) {
8257 if (
auto *BO = dyn_cast<BinaryOperator>(RHS)) {
8258 if (BO->isAdditiveOp()) {
8259 bool IsAdd = BO->getOpcode() == BO_Add;
8260 if (getInitLCDecl(BO->getLHS()) == LCDecl)
8261 return setStep(BO->getRHS(), !IsAdd);
8262 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
8263 return setStep(BO->getLHS(),
false);
8265 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
8266 bool IsAdd = CE->getOperator() == OO_Plus;
8267 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
8268 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8269 return setStep(CE->getArg(1), !IsAdd);
8270 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
8271 return setStep(CE->getArg(0),
false);
8274 if (dependent() || SemaRef.CurContext->isDependentContext())
8276 SemaRef.Diag(RHS->
getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
8281bool OpenMPIterationSpaceChecker::checkAndSetInc(
Expr *S) {
8296 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
8299 if (
auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
8300 if (!ExprTemp->cleanupsHaveSideEffects())
8301 S = ExprTemp->getSubExpr();
8303 IncrementSrcRange = S->getSourceRange();
8304 S = S->IgnoreParens();
8305 if (
auto *UO = dyn_cast<UnaryOperator>(S)) {
8306 if (UO->isIncrementDecrementOp() &&
8307 getInitLCDecl(UO->getSubExpr()) == LCDecl)
8308 return setStep(SemaRef
8309 .ActOnIntegerConstant(UO->getBeginLoc(),
8310 (UO->isDecrementOp() ? -1 : 1))
8313 }
else if (
auto *BO = dyn_cast<BinaryOperator>(S)) {
8314 switch (BO->getOpcode()) {
8317 if (getInitLCDecl(BO->getLHS()) == LCDecl)
8318 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
8321 if (getInitLCDecl(BO->getLHS()) == LCDecl)
8322 return checkAndSetIncRHS(BO->getRHS());
8327 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8328 switch (CE->getOperator()) {
8331 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8332 return setStep(SemaRef
8333 .ActOnIntegerConstant(
8335 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
8341 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8342 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
8345 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8346 return checkAndSetIncRHS(CE->getArg(1));
8352 if (dependent() || SemaRef.CurContext->isDependentContext())
8354 SemaRef.
Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
8355 << S->getSourceRange() << LCDecl;
8361 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8368 auto I = Captures.find(
Capture);
8369 if (I != Captures.end())
8382 bool TestIsStrictOp,
bool RoundToStep,
8383 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8384 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
8387 llvm::APSInt LRes, SRes;
8388 bool IsLowerConst =
false, IsStepConst =
false;
8392 IsLowerConst =
true;
8399 bool NoNeedToConvert = IsLowerConst && !RoundToStep &&
8400 ((!TestIsStrictOp && LRes.isNonNegative()) ||
8401 (TestIsStrictOp && LRes.isStrictlyPositive()));
8402 bool NeedToReorganize =
false;
8404 if (!NoNeedToConvert && IsLowerConst &&
8405 (TestIsStrictOp || (RoundToStep && IsStepConst))) {
8406 NoNeedToConvert =
true;
8408 unsigned BW = LRes.getBitWidth() > SRes.getBitWidth()
8409 ? LRes.getBitWidth()
8410 : SRes.getBitWidth();
8411 LRes = LRes.extend(BW + 1);
8412 LRes.setIsSigned(
true);
8413 SRes = SRes.extend(BW + 1);
8414 SRes.setIsSigned(
true);
8416 NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes;
8417 LRes = LRes.trunc(BW);
8419 if (TestIsStrictOp) {
8420 unsigned BW = LRes.getBitWidth();
8421 LRes = LRes.extend(BW + 1);
8422 LRes.setIsSigned(
true);
8425 NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes;
8427 LRes = LRes.trunc(BW);
8429 NeedToReorganize = NoNeedToConvert;
8432 bool IsUpperConst =
false;
8436 IsUpperConst =
true;
8438 if (NoNeedToConvert && IsLowerConst && IsUpperConst &&
8439 (!RoundToStep || IsStepConst)) {
8440 unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth()
8441 : URes.getBitWidth();
8442 LRes = LRes.extend(BW + 1);
8443 LRes.setIsSigned(
true);
8444 URes = URes.extend(BW + 1);
8445 URes.setIsSigned(
true);
8447 NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes;
8448 NeedToReorganize = NoNeedToConvert;
8453 if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) &&
8459 if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) ||
8462 LowerSize > UpperSize ? LowerSize : UpperSize, 0);
8473 if (!Lower || !Upper || NewStep.
isInvalid())
8479 if (NeedToReorganize) {
8493 S, DefaultLoc, BO_Add, Diff.
get(),
8503 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.
get());
8507 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
8523 S, DefaultLoc, BO_Sub, Diff.
get(),
8543 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Div, Diff.
get(), NewStep.
get());
8551Expr *OpenMPIterationSpaceChecker::buildNumIterations(
8553 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const {
8562 if (InitDependOnLC) {
8563 const LoopIterationSpace &IS = ResultIterSpaces[*InitDependOnLC - 1];
8564 if (!IS.MinValue || !IS.MaxValue)
8573 IS.CounterVar, MinValue.
get());
8578 SemaRef.
BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.
get(), LBVal);
8593 IS.CounterVar, MaxValue.
get());
8598 SemaRef.
BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.
get(), LBVal);
8606 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.
get(), Captures).get();
8607 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.
get(), Captures).get();
8608 if (!LBMin || !LBMax)
8612 SemaRef.
BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
8616 tryBuildCapture(SemaRef, MinLessMaxRes.
get(), Captures).get();
8619 if (*TestIsLessOp) {
8623 MinLessMax, LBMin, LBMax);
8626 LBVal = MinLB.
get();
8631 MinLessMax, LBMax, LBMin);
8634 LBVal = MaxLB.
get();
8639 if (CondDependOnLC) {
8640 const LoopIterationSpace &IS = ResultIterSpaces[*CondDependOnLC - 1];
8641 if (!IS.MinValue || !IS.MaxValue)
8650 IS.CounterVar, MinValue.
get());
8655 SemaRef.
BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.
get(), UBVal);
8670 IS.CounterVar, MaxValue.
get());
8675 SemaRef.
BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.
get(), UBVal);
8683 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.
get(), Captures).get();
8684 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.
get(), Captures).get();
8685 if (!UBMin || !UBMax)
8689 SemaRef.
BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
8692 Expr *MinGreaterMax =
8693 tryBuildCapture(SemaRef, MinGreaterMaxRes.
get(), Captures).get();
8696 if (*TestIsLessOp) {
8700 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
8703 UBVal = MaxUB.
get();
8708 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
8711 UBVal = MinUB.
get();
8714 Expr *UBExpr = TestIsLessOp.value() ? UBVal : LBVal;
8715 Expr *LBExpr = TestIsLessOp.value() ? LBVal : UBVal;
8716 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
8717 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
8718 if (!Upper || !Lower)
8721 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8722 Step, VarType, TestIsStrictOp,
8731 C.getTypeSize(
Type) >
C.getTypeSize(VarType);
8734 UseVarType ?
C.getTypeSize(VarType) :
C.getTypeSize(
Type);
8737 Type =
C.getIntTypeForBitwidth(NewSize, IsSigned);
8746 unsigned NewSize = (
C.getTypeSize(
Type) > 32) ? 64 : 32;
8747 if (NewSize !=
C.getTypeSize(
Type)) {
8748 if (NewSize <
C.getTypeSize(
Type)) {
8749 assert(NewSize == 64 &&
"incorrect loop var size");
8750 SemaRef.
Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
8751 << InitSrcRange << ConditionSrcRange;
8753 QualType NewType =
C.getIntTypeForBitwidth(
8755 C.getTypeSize(
Type) < NewSize);
8768std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
8769 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const {
8773 return std::make_pair(
nullptr,
nullptr);
8776 Expr *MinExpr =
nullptr;
8777 Expr *MaxExpr =
nullptr;
8778 Expr *LBExpr = TestIsLessOp.value() ? LB : UB;
8779 Expr *UBExpr = TestIsLessOp.value() ? UB : LB;
8780 bool LBNonRect = TestIsLessOp.value() ? InitDependOnLC.has_value()
8781 : CondDependOnLC.has_value();
8782 bool UBNonRect = TestIsLessOp.value() ? CondDependOnLC.has_value()
8783 : InitDependOnLC.has_value();
8785 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
8787 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
8788 if (!Upper || !Lower)
8789 return std::make_pair(
nullptr,
nullptr);
8799 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8800 Step, VarType, TestIsStrictOp,
8803 return std::make_pair(
nullptr,
nullptr);
8809 return std::make_pair(
nullptr,
nullptr);
8811 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
8813 return std::make_pair(
nullptr,
nullptr);
8814 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Mul, Diff.
get(), NewStep.
get());
8816 return std::make_pair(
nullptr,
nullptr);
8821 return std::make_pair(
nullptr,
nullptr);
8833 return std::make_pair(
nullptr,
nullptr);
8835 if (*TestIsLessOp) {
8839 S, DefaultLoc, BO_Add,
8843 return std::make_pair(
nullptr,
nullptr);
8848 S, DefaultLoc, BO_Sub,
8852 return std::make_pair(
nullptr,
nullptr);
8861 return std::make_pair(
nullptr,
nullptr);
8866 return std::make_pair(
nullptr,
nullptr);
8869 MaxExpr = Diff.
get();
8871 MinExpr = Diff.
get();
8873 return std::make_pair(MinExpr, MaxExpr);
8876Expr *OpenMPIterationSpaceChecker::buildFinalCondition(
Scope *S)
const {
8877 if (InitDependOnLC || CondDependOnLC)
8882Expr *OpenMPIterationSpaceChecker::buildPreCond(
8884 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const {
8889 if (CondDependOnLC || InitDependOnLC)
8900 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
8901 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
8907 TestIsLessOp.value() ? (TestIsStrictOp ? BO_LT : BO_LE)
8908 : (TestIsStrictOp ? BO_GT : BO_GE),
8909 NewLB.
get(), NewUB.
get());
8923DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
8924 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8925 DSAStackTy &DSA)
const {
8926 auto *VD = dyn_cast<VarDecl>(LCDecl);
8931 const DSAStackTy::DSAVarData Data =
8932 DSA.getTopDSA(LCDecl,
false);
8936 Captures.insert(std::make_pair(LCRef, Ref));
8942Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar()
const {
8948 isa<VarDecl>(LCDecl)
8959Expr *OpenMPIterationSpaceChecker::buildCounterInit()
const {
return LB; }
8962Expr *OpenMPIterationSpaceChecker::buildCounterStep()
const {
return Step; }
8964Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
8966 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
SourceLocation Loc,
8972 assert((OOK == OO_Plus || OOK == OO_Minus) &&
8973 "Expected only + or - operations for depend clauses.");
8985 TestIsLessOp.value() ? Cnt : tryBuildCapture(SemaRef, LB, Captures).get();
8987 TestIsLessOp.value() ? tryBuildCapture(SemaRef, LB, Captures).get() : Cnt;
8988 if (!Upper || !Lower)
8992 SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
8993 false,
false, Captures);
9002 assert(
getLangOpts().OpenMP &&
"OpenMP is not active.");
9003 assert(Init &&
"Expected loop in canonical form.");
9004 unsigned AssociatedLoops =
DSAStack->getAssociatedLoops();
9005 if (AssociatedLoops > 0 &&
9008 OpenMPIterationSpaceChecker ISC(*
this,
true,
9010 if (!ISC.checkAndSetInit(Init,
false)) {
9012 auto *VD = dyn_cast<VarDecl>(D);
9018 PrivateRef =
buildCapture(*
this, D, ISC.getLoopDeclRefExpr(),
9023 DSAStack->addLoopControlVariable(D, VD);
9026 DSAStack->resetPossibleLoopCounter();
9027 if (
auto *Var = dyn_cast_or_null<VarDecl>(LD))
9041 DSAStackTy::DSAVarData DVar =
9045 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
9048 ? (
DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
9051 DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
9052 (
LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
9053 DVar.CKind != OMPC_private))) ||
9055 DKind == OMPD_master_taskloop || DKind == OMPD_masked_taskloop ||
9056 DKind == OMPD_parallel_master_taskloop ||
9057 DKind == OMPD_parallel_masked_taskloop ||
9060 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
9061 (DVar.CKind != OMPC_private || DVar.RefExpr)) {
9062 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
9063 << getOpenMPClauseName(DVar.CKind)
9064 << getOpenMPDirectiveName(DKind)
9065 << getOpenMPClauseName(PredeterminedCKind);
9066 if (DVar.RefExpr ==
nullptr)
9067 DVar.CKind = PredeterminedCKind;
9070 }
else if (LoopDeclRefExpr) {
9075 if (DVar.CKind == OMPC_unknown)
9076 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
9081 DSAStack->setAssociatedLoops(AssociatedLoops - 1);
9089 unsigned CurrentNestedLoopCount,
unsigned NestedLoopCount,
9090 unsigned TotalNestedLoopCount,
Expr *CollapseLoopCountExpr,
9091 Expr *OrderedLoopCountExpr,
9094 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9099 if (
auto *CanonLoop = dyn_cast_or_null<OMPCanonicalLoop>(S))
9100 S = CanonLoop->getLoopStmt();
9101 auto *For = dyn_cast_or_null<ForStmt>(S);
9102 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
9104 if (!For && (SemaRef.
LangOpts.OpenMP <= 45 || !CXXFor)) {
9105 SemaRef.
Diag(S->getBeginLoc(), diag::err_omp_not_for)
9106 << (CollapseLoopCountExpr !=
nullptr || OrderedLoopCountExpr !=
nullptr)
9107 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
9108 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
9109 if (TotalNestedLoopCount > 1) {
9110 if (CollapseLoopCountExpr && OrderedLoopCountExpr)
9111 SemaRef.
Diag(DSA.getConstructLoc(),
9112 diag::note_omp_collapse_ordered_expr)
9115 else if (CollapseLoopCountExpr)
9117 diag::note_omp_collapse_ordered_expr)
9121 diag::note_omp_collapse_ordered_expr)
9126 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&
9132 OpenMPIterationSpaceChecker ISC(SemaRef, SupportsNonRectangular, DSA,
9133 For ? For->getForLoc() : CXXFor->getForLoc());
9136 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt();
9137 if (ISC.checkAndSetInit(Init))
9140 bool HasErrors =
false;
9143 if (
ValueDecl *LCDecl = ISC.getLoopDecl()) {
9153 SemaRef.
Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
9167 VarsWithImplicitDSA.erase(LCDecl);
9172 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
9175 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
9182 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
9183 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures);
9184 ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
9185 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
9192 ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
9193 ISC.buildCounterVar(Captures, DSA);
9194 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
9195 ISC.buildPrivateCounterVar();
9196 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
9197 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
9198 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
9199 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
9200 ISC.getConditionSrcRange();
9201 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
9202 ISC.getIncrementSrcRange();
9203 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
9204 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
9205 ISC.isStrictTestOp();
9206 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
9207 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
9208 ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
9209 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
9210 ISC.buildFinalCondition(DSA.getCurScope());
9211 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
9212 ISC.doesInitDependOnLC();
9213 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
9214 ISC.doesCondDependOnLC();
9215 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
9216 ISC.getLoopDependentIdx();
9219 (ResultIterSpaces[CurrentNestedLoopCount].PreCond ==
nullptr ||
9220 ResultIterSpaces[CurrentNestedLoopCount].NumIterations ==
nullptr ||
9221 ResultIterSpaces[CurrentNestedLoopCount].CounterVar ==
nullptr ||
9222 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar ==
nullptr ||
9223 ResultIterSpaces[CurrentNestedLoopCount].CounterInit ==
nullptr ||
9224 ResultIterSpaces[CurrentNestedLoopCount].CounterStep ==
nullptr);
9225 if (!HasErrors && DSA.isOrderedRegion()) {
9226 if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
9227 if (CurrentNestedLoopCount <
9228 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
9229 DSA.getOrderedRegionParam().second->setLoopNumIterations(
9230 CurrentNestedLoopCount,
9231 ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
9232 DSA.getOrderedRegionParam().second->setLoopCounter(
9233 CurrentNestedLoopCount,
9234 ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
9237 for (
auto &Pair : DSA.getDoacrossDependClauses()) {
9238 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
9242 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
9243 Pair.second.size() <= CurrentNestedLoopCount) {
9245 Pair.first->setLoopData(CurrentNestedLoopCount,
nullptr);
9249 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
9250 CntValue = ISC.buildOrderedLoopData(
9252 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9253 Pair.first->getDependencyLoc());
9255 CntValue = ISC.buildOrderedLoopData(
9257 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9258 Pair.first->getDependencyLoc(),
9259 Pair.second[CurrentNestedLoopCount].first,
9260 Pair.second[CurrentNestedLoopCount].second);
9261 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
9272 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9276 : tryBuildCapture(SemaRef, Start.
get(), Captures);
9297 bool IsNonRectangularLB,
9298 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures =
nullptr) {
9307 NewStep = tryBuildCapture(SemaRef, Step.
get(), *Captures);
9312 if (!Update.isUsable())
9322 if (Captures && !IsNonRectangularLB)
9323 NewStart = tryBuildCapture(SemaRef, Start.
get(), *Captures);
9332 Update.get()->getType()->isOverloadableType()) {
9337 if (Update.isUsable()) {
9339 SemaRef.
BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
9340 VarRef.
get(), SavedUpdate.
get());
9349 if (!Update.isUsable() || !UpdateVal.
isUsable()) {
9350 Update = SemaRef.
BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
9351 NewStart.
get(), SavedUpdate.
get());
9352 if (!Update.isUsable())
9359 if (!Update.isUsable())
9363 Update = SemaRef.
BuildBinOp(S, Loc, BO_Assign, VarRef.
get(), Update.get());
9375 unsigned HasBits =
C.getTypeSize(OldType);
9376 if (HasBits >= Bits)
9379 QualType NewType =
C.getIntTypeForBitwidth(Bits,
true);
9398 if (!PreInits.empty()) {
9409 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9410 if (!Captures.empty()) {
9412 for (
const auto &Pair : Captures)
9413 PreInits.push_back(Pair.second->getDecl());
9421 Expr *PostUpdate =
nullptr;
9422 if (!PostUpdates.empty()) {
9423 for (
Expr *E : PostUpdates) {
9429 PostUpdate = PostUpdate
9444 Expr *OrderedLoopCountExpr,
Stmt *AStmt,
Sema &SemaRef,
9447 OMPLoopBasedDirective::HelperExprs &Built) {
9448 unsigned NestedLoopCount = 1;
9449 bool SupportsNonPerfectlyNested = (SemaRef.
LangOpts.OpenMP >= 50) &&
9452 if (CollapseLoopCountExpr) {
9457 NestedLoopCount =
Result.Val.getInt().getLimitedValue();
9463 unsigned OrderedLoopCount = 1;
9464 if (OrderedLoopCountExpr) {
9471 if (
Result.getLimitedValue() < NestedLoopCount) {
9473 diag::err_omp_wrong_ordered_loop_count)
9476 diag::note_collapse_loop_count)
9479 OrderedLoopCount =
Result.getLimitedValue();
9487 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
9488 unsigned NumLoops = std::max(OrderedLoopCount, NestedLoopCount);
9490 if (!OMPLoopBasedDirective::doForAllLoops(
9492 SupportsNonPerfectlyNested, NumLoops,
9493 [DKind, &SemaRef, &DSA, NumLoops, NestedLoopCount,
9494 CollapseLoopCountExpr, OrderedLoopCountExpr, &VarsWithImplicitDSA,
9495 &IterSpaces, &Captures](
unsigned Cnt,
Stmt *CurStmt) {
9497 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
9498 NumLoops, CollapseLoopCountExpr, OrderedLoopCountExpr,
9499 VarsWithImplicitDSA, IterSpaces, Captures))
9501 if (Cnt > 0 && Cnt >= NestedLoopCount &&
9502 IterSpaces[Cnt].CounterVar) {
9505 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
9506 Captures[DRE] = DRE;
9512 Stmt *DependentPreInits = Transform->getPreInits();
9513 if (!DependentPreInits)
9515 for (
Decl *
C : cast<DeclStmt>(DependentPreInits)->getDeclGroup()) {
9518 Transform->getBeginLoc());
9519 Captures[Ref] = Ref;
9524 Built.clear( NestedLoopCount);
9527 return NestedLoopCount;
9560 auto PreCond =
ExprResult(IterSpaces[0].PreCond);
9561 Expr *N0 = IterSpaces[0].NumIterations;
9565 .PerformImplicitConversion(
9580 return NestedLoopCount;
9585 Scope *CurScope = DSA.getCurScope();
9586 for (
unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
9587 if (PreCond.isUsable()) {
9589 SemaRef.
BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
9590 PreCond.get(), IterSpaces[Cnt].PreCond);
9592 Expr *
N = IterSpaces[Cnt].NumIterations;
9594 AllCountsNeedLessThan32Bits &=
C.getTypeSize(
N->getType()) < 32;
9597 CurScope, Loc, BO_Mul, LastIteration32.
get(),
9605 CurScope, Loc, BO_Mul, LastIteration64.
get(),
9615 if (SemaRef.
getLangOpts().OpenMPOptimisticCollapse ||
9617 C.getTypeSize(LastIteration32.
get()->
getType()) == 32 &&
9618 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
9622 LastIteration64.
get(), SemaRef))))
9623 LastIteration = LastIteration32;
9642 LastIteration.
get(),
9654 tryBuildCapture(SemaRef, LastIteration.
get(), Captures);
9655 LastIteration = SaveRef;
9668 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
9697 buildVarDecl(SemaRef, InitLoc, StrideVType,
".omp.stride");
9706 UB.
get(), LastIteration.
get());
9709 LastIteration.
get(), UB.
get());
9710 EUB = SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, UB.
get(),
9735 CurScope, InitLoc, BO_GT, CombUB.
get(), LastIteration.
get());
9738 LastIteration.
get(), CombUB.
get());
9739 CombEUB = SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.
get(),
9748 "Unexpected number of parameters in loop combined directive");
9777 Init = SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, IV.
get(), RHS);
9789 SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, IV.
get(), CombRHS);
9795 bool UseStrictCompare =
9797 llvm::all_of(IterSpaces, [](
const LoopIterationSpace &LIS) {
9798 return LIS.IsStrictCompare;
9804 if (UseStrictCompare) {
9807 .
BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
9819 UseStrictCompare ? BO_LT : BO_LE, IV.
get(),
9822 NumIterations.
get());
9825 CombDistCond = SemaRef.
BuildBinOp(CurScope, CondLoc, BO_LT, IV.
get(),
9826 NumIterations.
get());
9831 Expr *BoundCombUB = CombUB.
get();
9832 if (UseStrictCompare) {
9836 CurScope, CondLoc, BO_Add, BoundCombUB,
9844 SemaRef.
BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
9845 IV.
get(), BoundCombUB);
9854 Inc = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Assign, IV.
get(), Inc.
get());
9863 ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
9896 CombNextLB = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.
get(),
9908 CombNextUB = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.
get(),
9922 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
9925 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.
get(), BoundUB);
9926 assert(DistCond.
isUsable() &&
"distribute cond expr was not built");
9930 assert(DistInc.
isUsable() &&
"distribute inc expr was not built");
9931 DistInc = SemaRef.
BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.
get(),
9935 assert(DistInc.
isUsable() &&
"distribute inc expr was not built");
9946 DistEUBLoc, NewPrevUB.
get());
9951 UB.
get(), NewPrevUB.
get());
9953 DistEUBLoc, DistEUBLoc, IsUBGreater.
get(), NewPrevUB.
get(), UB.
get());
9954 PrevEUB = SemaRef.
BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.
get(),
9962 Expr *BoundPrevUB = PrevUB.
get();
9963 if (UseStrictCompare) {
9967 CurScope, CondLoc, BO_Add, BoundPrevUB,
9975 SemaRef.
BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
9976 IV.
get(), BoundPrevUB);
9980 bool HasErrors =
false;
9981 Built.Counters.resize(NestedLoopCount);
9982 Built.Inits.resize(NestedLoopCount);
9983 Built.Updates.resize(NestedLoopCount);
9984 Built.Finals.resize(NestedLoopCount);
9985 Built.DependentCounters.resize(NestedLoopCount);
9986 Built.DependentInits.resize(NestedLoopCount);
9987 Built.FinalsConditions.resize(NestedLoopCount);
10005 for (
unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
10006 LoopIterationSpace &IS = IterSpaces[Cnt];
10012 for (
unsigned int K = Cnt + 1; K < NestedLoopCount; ++K)
10013 Prod = SemaRef.
BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.
get(),
10014 IterSpaces[K].NumIterations);
10019 if (Cnt + 1 < NestedLoopCount)
10033 if (Cnt + 1 < NestedLoopCount)
10034 Prod = SemaRef.
BuildBinOp(CurScope, UpdLoc, BO_Mul, Iter.
get(),
10038 Acc = SemaRef.
BuildBinOp(CurScope, UpdLoc, BO_Sub, Acc.
get(), Prod.
get());
10041 auto *VD =
cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
10047 IS.CounterInit, IS.IsNonRectangularLB, Captures);
10048 if (!Init.isUsable()) {
10053 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
10054 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
10055 if (!Update.isUsable()) {
10063 IS.CounterInit, IS.NumIterations, IS.CounterStep,
10064 IS.Subtract, IS.IsNonRectangularLB, &Captures);
10065 if (!Final.isUsable()) {
10070 if (!Update.isUsable() || !Final.isUsable()) {
10075 Built.Counters[Cnt] = IS.CounterVar;
10076 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
10077 Built.Inits[Cnt] = Init.get();
10078 Built.Updates[Cnt] = Update.get();
10079 Built.Finals[Cnt] = Final.get();
10080 Built.DependentCounters[Cnt] =
nullptr;
10081 Built.DependentInits[Cnt] =
nullptr;
10082 Built.FinalsConditions[Cnt] =
nullptr;
10083 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
10084 Built.DependentCounters[Cnt] =
10085 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx];
10086 Built.DependentInits[Cnt] =
10087 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx];
10088 Built.FinalsConditions[Cnt] = IS.FinalCondition;
10097 Built.IterationVarRef = IV.
get();
10098 Built.LastIteration = LastIteration.
get();
10099 Built.NumIterations = NumIterations.
get();
10100 Built.CalcLastIteration = SemaRef
10104 Built.PreCond = PreCond.get();
10106 Built.Cond =
Cond.get();
10107 Built.Init = Init.get();
10108 Built.Inc = Inc.
get();
10109 Built.LB = LB.
get();
10110 Built.UB = UB.
get();
10111 Built.IL = IL.
get();
10112 Built.ST = ST.
get();
10113 Built.EUB = EUB.
get();
10114 Built.NLB = NextLB.
get();
10115 Built.NUB = NextUB.
get();
10116 Built.PrevLB = PrevLB.
get();
10117 Built.PrevUB = PrevUB.
get();
10118 Built.DistInc = DistInc.
get();
10119 Built.PrevEUB = PrevEUB.
get();
10120 Built.DistCombinedFields.LB = CombLB.
get();
10121 Built.DistCombinedFields.UB = CombUB.
get();
10122 Built.DistCombinedFields.EUB = CombEUB.
get();
10123 Built.DistCombinedFields.Init = CombInit.
get();
10124 Built.DistCombinedFields.Cond = CombCond.
get();
10125 Built.DistCombinedFields.NLB = CombNextLB.
get();
10126 Built.DistCombinedFields.NUB = CombNextUB.
get();
10127 Built.DistCombinedFields.DistCond = CombDistCond.
get();
10128 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.
get();
10130 return NestedLoopCount;
10134 auto CollapseClauses =
10135 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
10136 if (CollapseClauses.begin() != CollapseClauses.end())
10137 return (*CollapseClauses.begin())->getNumForLoops();
10142 auto OrderedClauses =
10143 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
10144 if (OrderedClauses.begin() != OrderedClauses.end())
10145 return (*OrderedClauses.begin())->getNumForLoops();
10154 for (
const OMPClause *Clause : Clauses) {
10155 if (Clause->getClauseKind() == OMPC_safelen)
10157 else if (Clause->getClauseKind() == OMPC_simdlen)
10159 if (Safelen && Simdlen)
10163 if (Simdlen && Safelen) {
10177 llvm::APSInt SimdlenRes = SimdlenResult.
Val.
getInt();
10178 llvm::APSInt SafelenRes = SafelenResult.
Val.
getInt();
10183 if (SimdlenRes > SafelenRes) {
10185 diag::err_omp_wrong_simdlen_safelen_values)
10200 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
10201 OMPLoopBasedDirective::HelperExprs B;
10206 AStmt, *
this, *
DSAStack, VarsWithImplicitDSA, B);
10207 if (NestedLoopCount == 0)
10211 "omp simd loop exprs were not built");
10216 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
10218 B.NumIterations, *
this, CurScope,
10228 return OMPSimdDirective::Create(
Context, StartLoc, EndLoc, NestedLoopCount,
10229 Clauses, AStmt, B);
10239 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
10240 OMPLoopBasedDirective::HelperExprs B;
10245 AStmt, *
this, *
DSAStack, VarsWithImplicitDSA, B);
10246 if (NestedLoopCount == 0)
10250 "omp for loop exprs were not built");
10255 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
10257 B.NumIterations, *
this, CurScope,
10264 return OMPForDirective::Create(
10265 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10275 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
10276 OMPLoopBasedDirective::HelperExprs B;
10279 unsigned NestedLoopCount =
10282 VarsWithImplicitDSA, B);
10283 if (NestedLoopCount == 0)
10287 "omp for simd loop exprs were not built");
10292 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
10294 B.NumIterations, *
this, CurScope,
10304 return OMPForSimdDirective::Create(
Context, StartLoc, EndLoc, NestedLoopCount,
10305 Clauses, AStmt, B);
10315 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
10316 auto BaseStmt = AStmt;
10317 while (
auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
10319 if (
auto *
C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
10320 auto S =
C->children();
10321 if (S.begin() == S.end())
10325 for (
Stmt *SectionStmt : llvm::drop_begin(S)) {
10326 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
10328 Diag(SectionStmt->getBeginLoc(),
10329 diag::err_omp_sections_substmt_not_section);
10333 ->setHasCancel(
DSAStack->isCancelRegion());
10336 Diag(AStmt->
getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
10342 return OMPSectionsDirective::Create(
Context, StartLoc, EndLoc, Clauses, AStmt,
10343 DSAStack->getTaskgroupReductionRef(),
10356 return OMPSectionDirective::Create(
Context, StartLoc, EndLoc, AStmt,
10362 if (
auto *CE = dyn_cast<CallExpr>(E))
10363 if (CE->getDirectCallee())
10385 Expr *TargetCall =
nullptr;
10387 auto *E = dyn_cast<Expr>(S);
10389 Diag(S->getBeginLoc(), diag::err_omp_dispatch_statement_call);
10395 if (
auto *BO = dyn_cast<BinaryOperator>(E)) {
10396 if (BO->getOpcode() == BO_Assign)
10399 if (
auto *COCE = dyn_cast<CXXOperatorCallExpr>(E))
10400 if (COCE->getOperator() == OO_Equal)
10420 DSAStackTy *Stack) {
10421 bool ErrorFound =
false;
10423 if (
auto *LPC = dyn_cast<OMPLastprivateClause>(
C)) {
10424 for (
Expr *RefExpr : LPC->varlists()) {
10427 Expr *SimpleRefExpr = RefExpr;
10430 auto &&Info = Stack->isLoopControlVariable(D);
10432 S.
Diag(ELoc, diag::err_omp_lastprivate_loop_var_non_loop_iteration)
10433 << getOpenMPDirectiveName(K);
10463 OMPLoopDirective::HelperExprs B;
10467 AStmt, *
this, *
DSAStack, VarsWithImplicitDSA, B);
10468 if (NestedLoopCount == 0)
10472 "omp loop exprs were not built");
10476 NestedLoopCount, Clauses, AStmt, B);
10499 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10509 OMPLoopDirective::HelperExprs B;
10511 unsigned NestedLoopCount =
10514 VarsWithImplicitDSA, B);
10515 if (NestedLoopCount == 0)
10519 "omp loop exprs were not built");
10522 DSAStack->setParentTeamsRegionLoc(StartLoc);
10525 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10549 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10559 OMPLoopDirective::HelperExprs B;
10561 unsigned NestedLoopCount =
10564 VarsWithImplicitDSA, B);
10565 if (NestedLoopCount == 0)
10569 "omp loop exprs were not built");
10574 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10597 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10607 OMPLoopDirective::HelperExprs B;
10609 unsigned NestedLoopCount =
10612 VarsWithImplicitDSA, B);
10613 if (NestedLoopCount == 0)
10617 "omp loop exprs were not built");
10622 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10646 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10656 OMPLoopDirective::HelperExprs B;
10658 unsigned NestedLoopCount =
10661 VarsWithImplicitDSA, B);
10662 if (NestedLoopCount == 0)
10666 "omp loop exprs were not built");
10671 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10681 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
10688 const OMPClause *Copyprivate =
nullptr;
10689 for (
const OMPClause *Clause : Clauses) {
10690 if (Clause->getClauseKind() == OMPC_nowait)
10692 else if (Clause->getClauseKind() == OMPC_copyprivate)
10693 Copyprivate = Clause;
10694 if (Copyprivate && Nowait) {
10696 diag::err_omp_single_copyprivate_with_nowait);
10702 return OMPSingleDirective::Create(
Context, StartLoc, EndLoc, Clauses, AStmt);
10713 return OMPMasterDirective::Create(
Context, StartLoc, EndLoc, AStmt);
10734 bool ErrorFound =
false;
10737 bool DependentHint =
false;
10739 if (
C->getClauseKind() == OMPC_hint) {
10741 Diag(
C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
10747 DependentHint =
true;
10750 HintLoc =
C->getBeginLoc();
10756 const auto Pair =
DSAStack->getCriticalWithHint(DirName);
10757 if (Pair.first && DirName.
getName() && !DependentHint) {
10758 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
10759 Diag(StartLoc, diag::err_omp_critical_with_hint);
10761 Diag(HintLoc, diag::note_omp_critical_hint_here)
10762 << 0 <<
toString(Hint, 10,
false);
10764 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
10765 if (
const auto *
C = Pair.first->getSingleClause<
OMPHintClause>()) {
10766 Diag(
C->getBeginLoc(), diag::note_omp_critical_hint_here)
10771 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
10778 auto *Dir = OMPCriticalDirective::Create(
Context, DirName, StartLoc, EndLoc,
10780 if (!Pair.first && DirName.
getName() && !DependentHint)
10781 DSAStack->addCriticalWithHint(Dir, Hint);
10799 OMPLoopBasedDirective::HelperExprs B;
10802 unsigned NestedLoopCount =
10805 VarsWithImplicitDSA, B);
10806 if (NestedLoopCount == 0)
10810 "omp parallel for loop exprs were not built");
10815 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
10817 B.NumIterations, *
this, CurScope,
10824 return OMPParallelForDirective::Create(
10825 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10843 OMPLoopBasedDirective::HelperExprs B;
10846 unsigned NestedLoopCount =
10849 VarsWithImplicitDSA, B);
10850 if (NestedLoopCount == 0)
10856 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
10858 B.NumIterations, *
this, CurScope,
10868 return OMPParallelForSimdDirective::Create(
10869 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10879 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
10890 return OMPParallelMasterDirective::Create(
10891 Context, StartLoc, EndLoc, Clauses, AStmt,
10892 DSAStack->getTaskgroupReductionRef());
10902 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
10913 return OMPParallelMaskedDirective::Create(
10914 Context, StartLoc, EndLoc, Clauses, AStmt,
10915 DSAStack->getTaskgroupReductionRef());
10925 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
10926 auto BaseStmt = AStmt;
10927 while (
auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
10929 if (
auto *
C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
10930 auto S =
C->children();
10931 if (S.begin() == S.end())
10935 for (
Stmt *SectionStmt : llvm::drop_begin(S)) {
10936 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
10938 Diag(SectionStmt->getBeginLoc(),
10939 diag::err_omp_parallel_sections_substmt_not_section);
10943 ->setHasCancel(
DSAStack->isCancelRegion());
10947 diag::err_omp_parallel_sections_not_compound_stmt);
10953 return OMPParallelSectionsDirective::Create(
10954 Context, StartLoc, EndLoc, Clauses, AStmt,
10963 bool ErrorFound =
false;
10965 if (llvm::is_contained(MutuallyExclusiveClauses,
C->getClauseKind())) {
10969 S.
Diag(
C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
10970 << getOpenMPClauseName(
C->getClauseKind())
10991 {OMPC_detach, OMPC_mergeable}))
11004 return OMPTaskDirective::Create(
Context, StartLoc, EndLoc, Clauses, AStmt,
11010 return OMPTaskyieldDirective::Create(
Context, StartLoc, EndLoc);
11015 return OMPBarrierDirective::Create(
Context, StartLoc, EndLoc);
11021 return OMPTaskwaitDirective::Create(
Context, StartLoc, EndLoc, Clauses);
11031 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
11035 return OMPTaskgroupDirective::Create(
Context, StartLoc, EndLoc, Clauses,
11037 DSAStack->getTaskgroupReductionRef());
11046 if (
C->getClauseKind() == OMPC_flush)
11054 if (
C->getClauseKind() == OMPC_acq_rel ||
11055 C->getClauseKind() == OMPC_acquire ||
11056 C->getClauseKind() == OMPC_release) {
11057 if (MemOrderKind != OMPC_unknown) {
11058 Diag(
C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
11059 << getOpenMPDirectiveName(OMPD_flush) << 1
11061 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
11062 << getOpenMPClauseName(MemOrderKind);
11064 MemOrderKind =
C->getClauseKind();
11065 MemOrderLoc =
C->getBeginLoc();
11069 if (FC && OrderClause) {
11072 Diag(OrderClause->
getBeginLoc(), diag::note_omp_flush_order_clause_here)
11076 return OMPFlushDirective::Create(
Context, StartLoc, EndLoc, Clauses);
11082 if (Clauses.empty()) {
11083 Diag(StartLoc, diag::err_omp_depobj_expected);
11085 }
else if (Clauses[0]->getClauseKind() != OMPC_depobj) {
11086 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected);
11090 if (Clauses.size() > 2) {
11091 Diag(Clauses[2]->getBeginLoc(),
11092 diag::err_omp_depobj_single_clause_expected);
11094 }
else if (Clauses.size() < 1) {
11095 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected);
11098 return OMPDepobjDirective::Create(
Context, StartLoc, EndLoc, Clauses);
11105 if (Clauses.size() != 1) {
11106 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(),
11107 diag::err_omp_scan_single_clause_expected);
11112 Scope *ParentS = S->getParent();
11115 return StmtError(
Diag(StartLoc, diag::err_omp_orphaned_device_directive)
11116 << getOpenMPDirectiveName(OMPD_scan) << 5);
11120 if (
DSAStack->doesParentHasScanDirective()) {
11121 Diag(StartLoc, diag::err_omp_several_directives_in_region) <<
"scan";
11123 diag::note_omp_previous_directive)
11127 DSAStack->setParentHasScanDirective(StartLoc);
11135 const OMPClause *DependFound =
nullptr;
11136 const OMPClause *DependSourceClause =
nullptr;
11137 const OMPClause *DependSinkClause =
nullptr;
11138 bool ErrorFound =
false;
11142 if (
auto *DC = dyn_cast<OMPDependClause>(
C)) {
11144 if (DC->getDependencyKind() == OMPC_DEPEND_source) {
11145 if (DependSourceClause) {
11146 Diag(
C->getBeginLoc(), diag::err_omp_more_one_clause)
11147 << getOpenMPDirectiveName(OMPD_ordered)
11148 << getOpenMPClauseName(OMPC_depend) << 2;
11151 DependSourceClause =
C;
11153 if (DependSinkClause) {
11154 Diag(
C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
11158 }
else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
11159 if (DependSourceClause) {
11160 Diag(
C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
11164 DependSinkClause =
C;
11166 }
else if (
C->getClauseKind() == OMPC_threads) {
11168 }
else if (
C->getClauseKind() == OMPC_simd) {
11172 if (!ErrorFound && !SC &&
11177 Diag(StartLoc, diag::err_omp_prohibited_region_simd)
11178 << (
LangOpts.OpenMP >= 50 ? 1 : 0);
11180 }
else if (DependFound && (TC || SC)) {
11181 Diag(DependFound->
getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
11184 }
else if (DependFound && !
DSAStack->getParentOrderedRegionParam().first) {
11186 diag::err_omp_ordered_directive_without_param);
11188 }
else if (TC || Clauses.empty()) {
11189 if (
const Expr *Param =
DSAStack->getParentOrderedRegionParam().first) {
11191 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
11192 << (TC !=
nullptr);
11193 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1;
11197 if ((!AStmt && !DependFound) || ErrorFound)
11205 if (!DependFound) {
11206 if (
DSAStack->doesParentHasOrderedDirective()) {
11207 Diag(StartLoc, diag::err_omp_several_directives_in_region) <<
"ordered";
11209 diag::note_omp_previous_directive)
11213 DSAStack->setParentHasOrderedDirective(StartLoc);
11217 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
11222 return OMPOrderedDirective::Create(
Context, StartLoc, EndLoc, Clauses, AStmt);
11228class OpenMPAtomicUpdateChecker {
11230 enum ExprAnalysisErrorCode {
11234 NotABinaryOrUnaryExpression,
11236 NotAnUnaryIncDecExpression,
11242 NotABinaryExpression,
11245 NotABinaryOperator,
11248 NotAnUpdateExpression,
11274 OpenMPAtomicUpdateChecker(
Sema &SemaRef)
11275 : SemaRef(SemaRef),
X(nullptr), E(nullptr), UpdateExpr(nullptr),
11284 bool checkStatement(
Stmt *S,
unsigned DiagId = 0,
unsigned NoteId = 0);
11302 bool checkBinaryOperation(
BinaryOperator *AtomicBinOp,
unsigned DiagId = 0,
11303 unsigned NoteId = 0);
11306bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
11307 BinaryOperator *AtomicBinOp,
unsigned DiagId,
unsigned NoteId) {
11308 ExprAnalysisErrorCode ErrorFound = NoError;
11314 if (AtomicBinOp->
getOpcode() == BO_Assign) {
11316 if (
const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
11318 if (AtomicInnerBinOp->isMultiplicativeOp() ||
11319 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
11320 AtomicInnerBinOp->isBitwiseOp()) {
11321 Op = AtomicInnerBinOp->getOpcode();
11322 OpLoc = AtomicInnerBinOp->getOperatorLoc();
11323 Expr *LHS = AtomicInnerBinOp->getLHS();
11324 Expr *RHS = AtomicInnerBinOp->getRHS();
11325 llvm::FoldingSetNodeID XId, LHSId, RHSId;
11332 if (XId == LHSId) {
11335 }
else if (XId == RHSId) {
11339 ErrorLoc = AtomicInnerBinOp->getExprLoc();
11340 ErrorRange = AtomicInnerBinOp->getSourceRange();
11341 NoteLoc =
X->getExprLoc();
11342 NoteRange =
X->getSourceRange();
11343 ErrorFound = NotAnUpdateExpression;
11346 ErrorLoc = AtomicInnerBinOp->getExprLoc();
11347 ErrorRange = AtomicInnerBinOp->getSourceRange();
11348 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
11350 ErrorFound = NotABinaryOperator;
11355 ErrorFound = NotABinaryExpression;
11362 ErrorFound = NotAnAssignmentOp;
11364 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
11365 SemaRef.
Diag(ErrorLoc, DiagId) << ErrorRange;
11366 SemaRef.
Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
11370 E =
X = UpdateExpr =
nullptr;
11371 return ErrorFound != NoError;
11374bool OpenMPAtomicUpdateChecker::checkStatement(
Stmt *S,
unsigned DiagId,
11376 ExprAnalysisErrorCode ErrorFound = NoError;
11387 if (
auto *AtomicBody = dyn_cast<Expr>(S)) {
11388 AtomicBody = AtomicBody->IgnoreParenImpCasts();
11389 if (AtomicBody->getType()->isScalarType() ||
11390 AtomicBody->isInstantiationDependent()) {
11391 if (
const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
11392 AtomicBody->IgnoreParenImpCasts())) {
11395 AtomicCompAssignOp->getOpcode());
11396 OpLoc = AtomicCompAssignOp->getOperatorLoc();
11397 E = AtomicCompAssignOp->getRHS();
11400 }
else if (
auto *AtomicBinOp = dyn_cast<BinaryOperator>(
11401 AtomicBody->IgnoreParenImpCasts())) {
11403 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
11405 }
else if (
const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
11406 AtomicBody->IgnoreParenImpCasts())) {
11408 if (AtomicUnaryOp->isIncrementDecrementOp()) {
11410 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
11411 OpLoc = AtomicUnaryOp->getOperatorLoc();
11412 X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
11416 ErrorFound = NotAnUnaryIncDecExpression;
11417 ErrorLoc = AtomicUnaryOp->getExprLoc();
11418 ErrorRange = AtomicUnaryOp->getSourceRange();
11419 NoteLoc = AtomicUnaryOp->getOperatorLoc();
11422 }
else if (!AtomicBody->isInstantiationDependent()) {
11423 ErrorFound = NotABinaryOrUnaryExpression;
11424 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
11425 NoteRange = ErrorRange = AtomicBody->getSourceRange();
11428 ErrorFound = NotAScalarType;
11429 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
11430 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
11433 ErrorFound = NotAnExpression;
11434 NoteLoc = ErrorLoc = S->getBeginLoc();
11435 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
11437 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
11438 SemaRef.
Diag(ErrorLoc, DiagId) << ErrorRange;
11439 SemaRef.
Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
11443 E =
X = UpdateExpr =
nullptr;
11444 if (ErrorFound == NoError && E &&
X) {
11461 UpdateExpr =
Update.get();
11463 return ErrorFound != NoError;
11467llvm::FoldingSetNodeID getNodeId(
ASTContext &Context,
const Expr *S) {
11468 llvm::FoldingSetNodeID
Id;
11469 S->IgnoreParenImpCasts()->Profile(
Id, Context,
true);
11474bool checkIfTwoExprsAreSame(
ASTContext &Context,
const Expr *LHS,
11476 return getNodeId(Context, LHS) == getNodeId(Context, RHS);
11479class OpenMPAtomicCompareChecker {
11526 struct ErrorInfoTy {
11534 OpenMPAtomicCompareChecker(
Sema &S) : ContextRef(S.getASTContext()) {}
11537 bool checkStmt(
Stmt *S, ErrorInfoTy &ErrorInfo);
11540 Expr *getE()
const {
return E; }
11542 Expr *getCond()
const {
return C; }
11543 bool isXBinopExpr()
const {
return IsXBinopExpr; }
11562 bool IsXBinopExpr =
true;
11565 bool checkCondUpdateStmt(
IfStmt *S, ErrorInfoTy &ErrorInfo);
11568 bool checkCondExprStmt(
Stmt *S, ErrorInfoTy &ErrorInfo);
11571 bool checkType(ErrorInfoTy &ErrorInfo)
const;
11573 static bool CheckValue(
const Expr *E, ErrorInfoTy &ErrorInfo,
11574 bool ShouldBeLValue,
bool ShouldBeInteger =
false) {
11575 if (ShouldBeLValue && !E->
isLValue()) {
11576 ErrorInfo.Error = ErrorTy::XNotLValue;
11577 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->
getExprLoc();
11578 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->
getSourceRange();
11585 ErrorInfo.Error = ErrorTy::NotScalar;
11586 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->
getExprLoc();
11587 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->
getSourceRange();
11591 ErrorInfo.Error = ErrorTy::NotInteger;
11592 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->
getExprLoc();
11593 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->
getSourceRange();
11602bool OpenMPAtomicCompareChecker::checkCondUpdateStmt(
IfStmt *S,
11603 ErrorInfoTy &ErrorInfo) {
11604 auto *Then = S->getThen();
11605 if (
auto *CS = dyn_cast<CompoundStmt>(Then)) {
11606 if (CS->body_empty()) {
11607 ErrorInfo.Error = ErrorTy::NoStmt;
11608 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
11609 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->
getSourceRange();
11612 if (CS->size() > 1) {
11613 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
11614 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
11615 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
11618 Then = CS->body_front();
11621 auto *BO = dyn_cast<BinaryOperator>(Then);
11623 ErrorInfo.Error = ErrorTy::NotAnAssignment;
11624 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc();
11625 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange();
11628 if (BO->getOpcode() != BO_Assign) {
11629 ErrorInfo.Error = ErrorTy::NotAnAssignment;
11630 ErrorInfo.ErrorLoc = BO->getExprLoc();
11631 ErrorInfo.NoteLoc = BO->getOperatorLoc();
11632 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
11638 auto *
Cond = dyn_cast<BinaryOperator>(S->getCond());
11640 ErrorInfo.Error = ErrorTy::NotABinaryOp;
11641 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc();
11642 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange();
11646 switch (
Cond->getOpcode()) {
11650 if (checkIfTwoExprsAreSame(ContextRef,
X,
Cond->getLHS())) {
11651 E =
Cond->getRHS();
11652 }
else if (checkIfTwoExprsAreSame(ContextRef,
X,
Cond->getRHS())) {
11653 E =
Cond->getLHS();
11655 ErrorInfo.Error = ErrorTy::InvalidComparison;
11665 if (checkIfTwoExprsAreSame(ContextRef,
X,
Cond->getLHS()) &&
11666 checkIfTwoExprsAreSame(ContextRef, E,
Cond->getRHS())) {
11668 }
else if (checkIfTwoExprsAreSame(ContextRef, E,
Cond->getLHS()) &&
11669 checkIfTwoExprsAreSame(ContextRef,
X,
Cond->getRHS())) {
11671 IsXBinopExpr =
false;
11673 ErrorInfo.Error = ErrorTy::InvalidComparison;
11681 ErrorInfo.Error = ErrorTy::InvalidBinaryOp;
11687 if (S->getElse()) {
11688 ErrorInfo.Error = ErrorTy::UnexpectedElse;
11689 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getElse()->getBeginLoc();
11690 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getElse()->getSourceRange();
11697bool OpenMPAtomicCompareChecker::checkCondExprStmt(
Stmt *S,
11698 ErrorInfoTy &ErrorInfo) {
11699 auto *BO = dyn_cast<BinaryOperator>(S);
11701 ErrorInfo.Error = ErrorTy::NotAnAssignment;
11702 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
11703 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
11706 if (BO->getOpcode() != BO_Assign) {
11707 ErrorInfo.Error = ErrorTy::NotAnAssignment;
11708 ErrorInfo.ErrorLoc = BO->getExprLoc();
11709 ErrorInfo.NoteLoc = BO->getOperatorLoc();
11710 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
11716 auto *CO = dyn_cast<ConditionalOperator>(BO->getRHS()->IgnoreParenImpCasts());
11718 ErrorInfo.Error = ErrorTy::NotCondOp;
11719 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getRHS()->getExprLoc();
11720 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getRHS()->getSourceRange();
11724 if (!checkIfTwoExprsAreSame(ContextRef,
X, CO->getFalseExpr())) {
11725 ErrorInfo.Error = ErrorTy::WrongFalseExpr;
11726 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getFalseExpr()->getExprLoc();
11727 ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
11728 CO->getFalseExpr()->getSourceRange();
11732 auto *
Cond = dyn_cast<BinaryOperator>(CO->getCond());
11734 ErrorInfo.Error = ErrorTy::NotABinaryOp;
11735 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getCond()->getExprLoc();
11736 ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
11737 CO->getCond()->getSourceRange();
11741 switch (
Cond->getOpcode()) {
11744 D = CO->getTrueExpr();
11745 if (checkIfTwoExprsAreSame(ContextRef,
X,
Cond->getLHS())) {
11746 E =
Cond->getRHS();
11747 }
else if (checkIfTwoExprsAreSame(ContextRef,
X,
Cond->getRHS())) {
11748 E =
Cond->getLHS();
11750 ErrorInfo.Error = ErrorTy::InvalidComparison;
11759 E = CO->getTrueExpr();
11760 if (checkIfTwoExprsAreSame(ContextRef,
X,
Cond->getLHS()) &&
11761 checkIfTwoExprsAreSame(ContextRef, E,
Cond->getRHS())) {
11763 }
else if (checkIfTwoExprsAreSame(ContextRef, E,
Cond->getLHS()) &&
11764 checkIfTwoExprsAreSame(ContextRef,
X,
Cond->getRHS())) {
11766 IsXBinopExpr =
false;
11768 ErrorInfo.Error = ErrorTy::InvalidComparison;
11776 ErrorInfo.Error = ErrorTy::InvalidBinaryOp;
11785bool OpenMPAtomicCompareChecker::checkType(ErrorInfoTy &ErrorInfo)
const {
11787 assert(
X && E &&
"X and E cannot be nullptr");
11789 if (!CheckValue(
X, ErrorInfo,
true))
11792 if (!CheckValue(E, ErrorInfo,
false))
11795 if (D && !CheckValue(D, ErrorInfo,
false))
11801bool OpenMPAtomicCompareChecker::checkStmt(
11802 Stmt *S, OpenMPAtomicCompareChecker::ErrorInfoTy &ErrorInfo) {
11803 auto *CS = dyn_cast<CompoundStmt>(S);
11805 if (CS->body_empty()) {
11806 ErrorInfo.Error = ErrorTy::NoStmt;
11807 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
11808 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->
getSourceRange();
11812 if (CS->size() != 1) {
11813 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
11814 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
11815 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->
getSourceRange();
11818 S = CS->body_front();
11823 if (
auto *IS = dyn_cast<IfStmt>(S)) {
11829 Res = checkCondUpdateStmt(IS, ErrorInfo);
11835 Res = checkCondExprStmt(S, ErrorInfo);
11841 return checkType(ErrorInfo);
11844class OpenMPAtomicCompareCaptureChecker final
11845 :
public OpenMPAtomicCompareChecker {
11847 OpenMPAtomicCompareCaptureChecker(
Sema &S) : OpenMPAtomicCompareChecker(S) {}
11855 bool checkStmt(
Stmt *S, ErrorInfoTy &ErrorInfo);
11858 bool checkType(ErrorInfoTy &ErrorInfo);
11870 bool checkForm3(
IfStmt *S, ErrorInfoTy &ErrorInfo);
11874 bool checkForm45(
Stmt *S, ErrorInfoTy &ErrorInfo);
11886bool OpenMPAtomicCompareCaptureChecker::checkType(ErrorInfoTy &ErrorInfo) {
11887 if (!OpenMPAtomicCompareChecker::checkType(ErrorInfo))
11890 if (
V && !CheckValue(
V, ErrorInfo,
true))
11893 if (R && !CheckValue(R, ErrorInfo,
true,
true))
11899bool OpenMPAtomicCompareCaptureChecker::checkForm3(
IfStmt *S,
11900 ErrorInfoTy &ErrorInfo) {
11903 auto *Then = S->getThen();
11904 if (
auto *CS = dyn_cast<CompoundStmt>(Then)) {
11905 if (CS->body_empty()) {
11906 ErrorInfo.Error = ErrorTy::NoStmt;
11907 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
11908 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->
getSourceRange();
11911 if (CS->size() > 1) {
11912 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
11913 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
11914 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->
getSourceRange();
11917 Then = CS->body_front();
11920 auto *BO = dyn_cast<BinaryOperator>(Then);
11922 ErrorInfo.Error = ErrorTy::NotAnAssignment;
11923 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc();
11924 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange();
11927 if (BO->getOpcode() != BO_Assign) {
11928 ErrorInfo.Error = ErrorTy::NotAnAssignment;
11929 ErrorInfo.ErrorLoc = BO->getExprLoc();
11930 ErrorInfo.NoteLoc = BO->getOperatorLoc();
11931 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
11938 auto *
Cond = dyn_cast<BinaryOperator>(S->getCond());
11940 ErrorInfo.Error = ErrorTy::NotABinaryOp;
11941 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc();
11942 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange();
11945 if (
Cond->getOpcode() != BO_EQ) {
11946 ErrorInfo.Error = ErrorTy::NotEQ;
11952 if (checkIfTwoExprsAreSame(ContextRef,
X,
Cond->getLHS())) {
11953 E =
Cond->getRHS();
11954 }
else if (checkIfTwoExprsAreSame(ContextRef,
X,
Cond->getRHS())) {
11955 E =
Cond->getLHS();
11957 ErrorInfo.Error = ErrorTy::InvalidComparison;
11965 if (!S->getElse()) {
11966 ErrorInfo.Error = ErrorTy::NoElse;
11967 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
11968 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
11972 auto *Else = S->getElse();
11973 if (
auto *CS = dyn_cast<CompoundStmt>(Else)) {
11974 if (CS->body_empty()) {
11975 ErrorInfo.Error = ErrorTy::NoStmt;
11976 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
11977 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->
getSourceRange();
11980 if (CS->size() > 1) {
11981 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
11982 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
11983 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
11986 Else = CS->body_front();
11989 auto *ElseBO = dyn_cast<BinaryOperator>(Else);
11991 ErrorInfo.Error = ErrorTy::NotAnAssignment;
11992 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc();
11993 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange();
11996 if (ElseBO->getOpcode() != BO_Assign) {
11997 ErrorInfo.Error = ErrorTy::NotAnAssignment;
11998 ErrorInfo.ErrorLoc = ElseBO->getExprLoc();
11999 ErrorInfo.NoteLoc = ElseBO->getOperatorLoc();
12000 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange();
12004 if (!checkIfTwoExprsAreSame(ContextRef,
X, ElseBO->getRHS())) {
12005 ErrorInfo.Error = ErrorTy::InvalidAssignment;
12006 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseBO->getRHS()->getExprLoc();
12007 ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12008 ElseBO->getRHS()->getSourceRange();
12012 V = ElseBO->getLHS();
12014 return checkType(ErrorInfo);
12017bool OpenMPAtomicCompareCaptureChecker::checkForm45(
Stmt *S,
12018 ErrorInfoTy &ErrorInfo) {
12022 assert(CS->size() == 2 &&
"CompoundStmt size is not expected");
12025 assert(S1->getOpcode() == BO_Assign &&
"unexpected binary operator");
12027 if (!checkIfTwoExprsAreSame(ContextRef, S1->getLHS(), S2->getCond())) {
12028 ErrorInfo.Error = ErrorTy::InvalidCondition;
12029 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getCond()->getExprLoc();
12030 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S1->getLHS()->getSourceRange();
12036 auto *Then = S2->getThen();
12037 if (
auto *ThenCS = dyn_cast<CompoundStmt>(Then)) {
12038 if (ThenCS->body_empty()) {
12039 ErrorInfo.Error = ErrorTy::NoStmt;
12040 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc();
12041 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange();
12044 if (ThenCS->size() > 1) {
12045 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12046 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc();
12047 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange();
12050 Then = ThenCS->body_front();
12053 auto *ThenBO = dyn_cast<BinaryOperator>(Then);
12055 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12056 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getBeginLoc();
12057 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S2->getSourceRange();
12060 if (ThenBO->getOpcode() != BO_Assign) {
12061 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12062 ErrorInfo.ErrorLoc = ThenBO->getExprLoc();
12063 ErrorInfo.NoteLoc = ThenBO->getOperatorLoc();
12064 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenBO->getSourceRange();
12068 X = ThenBO->getLHS();
12069 D = ThenBO->getRHS();
12072 if (BO->getOpcode() != BO_EQ) {
12073 ErrorInfo.Error = ErrorTy::NotEQ;
12074 ErrorInfo.ErrorLoc = BO->getExprLoc();
12075 ErrorInfo.NoteLoc = BO->getOperatorLoc();
12076 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12082 if (checkIfTwoExprsAreSame(ContextRef,
X, BO->getLHS())) {
12084 }
else if (checkIfTwoExprsAreSame(ContextRef,
X, BO->getRHS())) {
12087 ErrorInfo.Error = ErrorTy::InvalidComparison;
12088 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getExprLoc();
12089 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12093 if (S2->getElse()) {
12096 auto *Else = S2->getElse();
12097 if (
auto *ElseCS = dyn_cast<CompoundStmt>(Else)) {
12098 if (ElseCS->body_empty()) {
12099 ErrorInfo.Error = ErrorTy::NoStmt;
12100 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc();
12101 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange();
12104 if (ElseCS->size() > 1) {
12105 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12106 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc();
12107 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange();
12110 Else = ElseCS->body_front();
12113 auto *ElseBO = dyn_cast<BinaryOperator>(Else);
12115 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12116 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc();
12117 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange();
12120 if (ElseBO->getOpcode() != BO_Assign) {
12121 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12122 ErrorInfo.ErrorLoc = ElseBO->getExprLoc();
12123 ErrorInfo.NoteLoc = ElseBO->getOperatorLoc();
12124 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange();
12127 if (!checkIfTwoExprsAreSame(ContextRef,
X, ElseBO->getRHS())) {
12128 ErrorInfo.Error = ErrorTy::InvalidAssignment;
12129 ErrorInfo.ErrorLoc = ElseBO->getRHS()->getExprLoc();
12130 ErrorInfo.NoteLoc =
X->getExprLoc();
12131 ErrorInfo.ErrorRange = ElseBO->getRHS()->getSourceRange();
12132 ErrorInfo.NoteRange =
X->getSourceRange();
12136 V = ElseBO->getLHS();
12139 return checkType(ErrorInfo);
12142bool OpenMPAtomicCompareCaptureChecker::checkStmt(
Stmt *S,
12143 ErrorInfoTy &ErrorInfo) {
12145 if (
auto *IS = dyn_cast<IfStmt>(S))
12146 return checkForm3(IS, ErrorInfo);
12148 auto *CS = dyn_cast<CompoundStmt>(S);
12150 ErrorInfo.Error = ErrorTy::NotCompoundStmt;
12151 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
12152 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12155 if (CS->body_empty()) {
12156 ErrorInfo.Error = ErrorTy::NoStmt;
12157 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
12158 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->
getSourceRange();
12163 if (CS->size() == 1) {
12164 auto *IS = dyn_cast<IfStmt>(CS->body_front());
12166 ErrorInfo.Error = ErrorTy::NotIfStmt;
12167 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->body_front()->
getBeginLoc();
12168 ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12173 return checkForm3(IS, ErrorInfo);
12174 }
else if (CS->size() == 2) {
12175 auto *S1 = CS->body_front();
12176 auto *S2 = CS->body_back();
12178 Stmt *UpdateStmt =
nullptr;
12179 Stmt *CondUpdateStmt =
nullptr;
12181 if (
auto *BO = dyn_cast<BinaryOperator>(S1)) {
12184 CondUpdateStmt = S2;
12186 if (isa<BinaryOperator>(BO->getRHS()->IgnoreImpCasts()) &&
12188 return checkForm45(CS, ErrorInfo);
12194 CondUpdateStmt = S1;
12197 auto CheckCondUpdateStmt = [
this, &ErrorInfo](
Stmt *CUS) {
12198 auto *IS = dyn_cast<IfStmt>(CUS);
12200 ErrorInfo.Error = ErrorTy::NotIfStmt;
12201 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CUS->getBeginLoc();
12202 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CUS->getSourceRange();
12206 if (!checkCondUpdateStmt(IS, ErrorInfo))
12213 auto CheckUpdateStmt = [
this, &ErrorInfo](
Stmt *US) {
12214 auto *BO = dyn_cast<BinaryOperator>(US);
12216 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12217 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = US->getBeginLoc();
12218 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = US->getSourceRange();
12221 if (BO->getOpcode() != BO_Assign) {
12222 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12223 ErrorInfo.ErrorLoc = BO->getExprLoc();
12224 ErrorInfo.NoteLoc = BO->getOperatorLoc();
12225 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12228 if (!checkIfTwoExprsAreSame(ContextRef, this->X, BO->getRHS())) {
12229 ErrorInfo.Error = ErrorTy::InvalidAssignment;
12230 ErrorInfo.ErrorLoc = BO->getRHS()->getExprLoc();
12232 ErrorInfo.ErrorRange = BO->getRHS()->getSourceRange();
12237 this->
V = BO->getLHS();
12242 if (!CheckCondUpdateStmt(CondUpdateStmt))
12244 if (!CheckUpdateStmt(UpdateStmt))
12247 ErrorInfo.Error = ErrorTy::MoreThanTwoStmts;
12248 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
12249 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->
getSourceRange();
12253 return checkType(ErrorInfo);
12262 DSAStack->addAtomicDirectiveLoc(StartLoc);
12275 bool MutexClauseEncountered =
false;
12276 llvm::SmallSet<OpenMPClauseKind, 2> EncounteredAtomicKinds;
12278 switch (
C->getClauseKind()) {
12282 MutexClauseEncountered =
true;
12285 case OMPC_compare: {
12286 if (AtomicKind != OMPC_unknown && MutexClauseEncountered) {
12287 Diag(
C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
12289 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
12290 << getOpenMPClauseName(AtomicKind);
12292 AtomicKind =
C->getClauseKind();
12293 AtomicKindLoc =
C->getBeginLoc();
12294 if (!EncounteredAtomicKinds.insert(
C->getClauseKind()).second) {
12295 Diag(
C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
12297 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
12298 << getOpenMPClauseName(AtomicKind);
12307 case OMPC_relaxed: {
12308 if (MemOrderKind != OMPC_unknown) {
12309 Diag(
C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
12310 << getOpenMPDirectiveName(OMPD_atomic) << 0
12312 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
12313 << getOpenMPClauseName(MemOrderKind);
12315 MemOrderKind =
C->getClauseKind();
12316 MemOrderLoc =
C->getBeginLoc();
12324 llvm_unreachable(
"unknown clause is encountered");
12327 bool IsCompareCapture =
false;
12328 if (EncounteredAtomicKinds.contains(OMPC_compare) &&
12329 EncounteredAtomicKinds.contains(OMPC_capture)) {
12330 IsCompareCapture =
true;
12331 AtomicKind = OMPC_compare;
12340 if ((AtomicKind == OMPC_read &&
12341 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) ||
12342 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update ||
12343 AtomicKind == OMPC_unknown) &&
12344 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) {
12346 if (AtomicKind == OMPC_unknown)
12348 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause)
12349 << getOpenMPClauseName(AtomicKind)
12350 << (AtomicKind == OMPC_unknown ? 1 : 0)
12351 << getOpenMPClauseName(MemOrderKind);
12352 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
12353 << getOpenMPClauseName(MemOrderKind);
12356 Stmt *Body = AStmt;
12357 if (
auto *EWC = dyn_cast<ExprWithCleanups>(Body))
12358 Body = EWC->getSubExpr();
12363 Expr *UE =
nullptr;
12365 Expr *CE =
nullptr;
12392 if (AtomicKind == OMPC_read) {
12399 } ErrorFound = NoError;
12404 if (
const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12405 const auto *AtomicBinOp =
12406 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12407 if (AtomicBinOp && AtomicBinOp->
getOpcode() == BO_Assign) {
12410 if ((
X->isInstantiationDependent() ||
X->getType()->isScalarType()) &&
12411 (
V->isInstantiationDependent() ||
V->getType()->isScalarType())) {
12412 if (!
X->isLValue() || !
V->isLValue()) {
12414 ErrorFound = NotAnLValue;
12420 }
else if (!
X->isInstantiationDependent() ||
12421 !
V->isInstantiationDependent()) {
12422 const Expr *NotScalarExpr =
12423 (
X->isInstantiationDependent() ||
X->getType()->isScalarType())
12426 ErrorFound = NotAScalarType;
12432 }
else if (!AtomicBody->isInstantiationDependent()) {
12433 ErrorFound = NotAnAssignmentOp;
12434 ErrorLoc = AtomicBody->getExprLoc();
12435 ErrorRange = AtomicBody->getSourceRange();
12437 : AtomicBody->getExprLoc();
12439 : AtomicBody->getSourceRange();
12442 ErrorFound = NotAnExpression;
12444 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
12446 if (ErrorFound != NoError) {
12447 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
12449 Diag(NoteLoc, diag::note_omp_atomic_read_write)
12450 << ErrorFound << NoteRange;
12455 }
else if (AtomicKind == OMPC_write) {
12462 } ErrorFound = NoError;
12467 if (
const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12468 const auto *AtomicBinOp =
12469 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12470 if (AtomicBinOp && AtomicBinOp->
getOpcode() == BO_Assign) {
12472 E = AtomicBinOp->
getRHS();
12473 if ((
X->isInstantiationDependent() ||
X->getType()->isScalarType()) &&
12475 if (!
X->isLValue()) {
12476 ErrorFound = NotAnLValue;
12479 NoteLoc =
X->getExprLoc();
12480 NoteRange =
X->getSourceRange();
12482 }
else if (!
X->isInstantiationDependent() ||
12484 const Expr *NotScalarExpr =
12485 (
X->isInstantiationDependent() ||
X->getType()->isScalarType())
12488 ErrorFound = NotAScalarType;
12494 }
else if (!AtomicBody->isInstantiationDependent()) {
12495 ErrorFound = NotAnAssignmentOp;
12496 ErrorLoc = AtomicBody->getExprLoc();
12497 ErrorRange = AtomicBody->getSourceRange();
12499 : AtomicBody->getExprLoc();
12501 : AtomicBody->getSourceRange();
12504 ErrorFound = NotAnExpression;
12506 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
12508 if (ErrorFound != NoError) {
12509 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
12511 Diag(NoteLoc, diag::note_omp_atomic_read_write)
12512 << ErrorFound << NoteRange;
12517 }
else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
12526 OpenMPAtomicUpdateChecker Checker(*
this);
12527 if (Checker.checkStatement(
12529 (AtomicKind == OMPC_update)
12530 ? diag::err_omp_atomic_update_not_expression_statement
12531 : diag::err_omp_atomic_not_expression_statement,
12532 diag::note_omp_atomic_update))
12535 E = Checker.getExpr();
12536 X = Checker.getX();
12537 UE = Checker.getUpdateExpr();
12540 }
else if (AtomicKind == OMPC_capture) {
12543 NotACompoundStatement,
12544 NotTwoSubstatements,
12545 NotASpecificExpression,
12547 } ErrorFound = NoError;
12550 if (
const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12559 const auto *AtomicBinOp =
12560 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12561 if (AtomicBinOp && AtomicBinOp->
getOpcode() == BO_Assign) {
12564 OpenMPAtomicUpdateChecker Checker(*
this);
12565 if (Checker.checkStatement(
12566 Body, diag::err_omp_atomic_capture_not_expression_statement,
12567 diag::note_omp_atomic_update))
12569 E = Checker.getExpr();
12570 X = Checker.getX();
12571 UE = Checker.getUpdateExpr();
12574 }
else if (!AtomicBody->isInstantiationDependent()) {
12575 ErrorLoc = AtomicBody->getExprLoc();
12576 ErrorRange = AtomicBody->getSourceRange();
12578 : AtomicBody->getExprLoc();
12580 : AtomicBody->getSourceRange();
12581 ErrorFound = NotAnAssignmentOp;
12583 if (ErrorFound != NoError) {
12584 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
12586 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
12590 UE =
V = E =
X =
nullptr;
12608 if (
auto *CS = dyn_cast<CompoundStmt>(Body)) {
12610 if (CS->size() == 2) {
12612 Stmt *Second = CS->body_back();
12613 if (
auto *EWC = dyn_cast<ExprWithCleanups>(
First))
12614 First = EWC->getSubExpr()->IgnoreParenImpCasts();
12615 if (
auto *EWC = dyn_cast<ExprWithCleanups>(Second))
12616 Second = EWC->getSubExpr()->IgnoreParenImpCasts();
12618 OpenMPAtomicUpdateChecker Checker(*
this);
12619 bool IsUpdateExprFound = !Checker.checkStatement(Second);
12621 if (IsUpdateExprFound) {
12622 BinOp = dyn_cast<BinaryOperator>(
First);
12623 IsUpdateExprFound = BinOp && BinOp->
getOpcode() == BO_Assign;
12635 llvm::FoldingSetNodeID XId, PossibleXId;
12636 Checker.getX()->Profile(XId,
Context,
true);
12638 IsUpdateExprFound = XId == PossibleXId;
12639 if (IsUpdateExprFound) {
12641 X = Checker.getX();
12642 E = Checker.getExpr();
12643 UE = Checker.getUpdateExpr();
12648 if (!IsUpdateExprFound) {
12649 IsUpdateExprFound = !Checker.checkStatement(
First);
12651 if (IsUpdateExprFound) {
12652 BinOp = dyn_cast<BinaryOperator>(Second);
12653 IsUpdateExprFound = BinOp && BinOp->
getOpcode() == BO_Assign;
12665 llvm::FoldingSetNodeID XId, PossibleXId;
12666 Checker.getX()->Profile(XId,
Context,
true);
12668 IsUpdateExprFound = XId == PossibleXId;
12669 if (IsUpdateExprFound) {
12671 X = Checker.getX();
12672 E = Checker.getExpr();
12673 UE = Checker.getUpdateExpr();
12679 if (!IsUpdateExprFound) {
12681 auto *FirstExpr = dyn_cast<Expr>(
First);
12682 auto *SecondExpr = dyn_cast<Expr>(Second);
12683 if (!FirstExpr || !SecondExpr ||
12684 !(FirstExpr->isInstantiationDependent() ||
12685 SecondExpr->isInstantiationDependent())) {
12686 auto *FirstBinOp = dyn_cast<BinaryOperator>(
First);
12687 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
12688 ErrorFound = NotAnAssignmentOp;
12689 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
12690 :
First->getBeginLoc();
12691 NoteRange = ErrorRange = FirstBinOp
12692 ? FirstBinOp->getSourceRange()
12695 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
12696 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
12697 ErrorFound = NotAnAssignmentOp;
12698 NoteLoc = ErrorLoc = SecondBinOp
12699 ? SecondBinOp->getOperatorLoc()
12701 NoteRange = ErrorRange =
12702 SecondBinOp ? SecondBinOp->getSourceRange()
12705 Expr *PossibleXRHSInFirst =
12707 Expr *PossibleXLHSInSecond =
12709 llvm::FoldingSetNodeID X1Id, X2Id;
12714 IsUpdateExprFound = X1Id == X2Id;
12715 if (IsUpdateExprFound) {
12716 V = FirstBinOp->getLHS();
12717 X = SecondBinOp->getLHS();
12718 E = SecondBinOp->getRHS();
12723 ErrorFound = NotASpecificExpression;
12724 ErrorLoc = FirstBinOp->getExprLoc();
12725 ErrorRange = FirstBinOp->getSourceRange();
12726 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
12727 NoteRange = SecondBinOp->getRHS()->getSourceRange();
12735 NoteRange = ErrorRange =
12737 ErrorFound = NotTwoSubstatements;
12741 NoteRange = ErrorRange =
12743 ErrorFound = NotACompoundStatement;
12746 if (ErrorFound != NoError) {
12747 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
12749 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
12753 UE =
V = E =
X =
nullptr;
12754 }
else if (AtomicKind == OMPC_compare) {
12755 if (IsCompareCapture) {
12756 OpenMPAtomicCompareCaptureChecker::ErrorInfoTy ErrorInfo;
12757 OpenMPAtomicCompareCaptureChecker Checker(*
this);
12758 if (!Checker.checkStmt(Body, ErrorInfo)) {
12759 Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare_capture)
12760 << ErrorInfo.ErrorRange;
12761 Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare)
12762 << ErrorInfo.Error << ErrorInfo.NoteRange;
12765 X = Checker.getX();
12766 E = Checker.getE();
12767 D = Checker.getD();
12768 CE = Checker.getCond();
12769 V = Checker.getV();
12770 R = Checker.getR();
12776 OpenMPAtomicCompareChecker::ErrorInfoTy ErrorInfo;
12777 OpenMPAtomicCompareChecker Checker(*
this);
12778 if (!Checker.checkStmt(Body, ErrorInfo)) {
12779 Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare)
12780 << ErrorInfo.ErrorRange;
12781 Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare)
12782 << ErrorInfo.Error << ErrorInfo.NoteRange;
12785 X = Checker.getX();
12786 E = Checker.getE();
12787 D = Checker.getD();
12788 CE = Checker.getCond();
12796 return OMPAtomicDirective::Create(
12797 Context, StartLoc, EndLoc, Clauses, AStmt,
12816 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12830 if (
DSAStack->hasInnerTeamsRegion()) {
12832 bool OMPTeamsFound =
true;
12833 if (
const auto *CS = dyn_cast<CompoundStmt>(S)) {
12834 auto I = CS->body_begin();
12835 while (I != CS->body_end()) {
12836 const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
12840 OMPTeamsFound =
false;
12845 assert(I != CS->body_end() &&
"Not found statement");
12848 const auto *OED = dyn_cast<OMPExecutableDirective>(S);
12851 if (!OMPTeamsFound) {
12852 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
12854 diag::note_omp_nested_teams_construct_here);
12855 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
12881 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12894 Context, StartLoc, EndLoc, Clauses, AStmt,
12912 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12922 OMPLoopBasedDirective::HelperExprs B;
12925 unsigned NestedLoopCount =
12928 VarsWithImplicitDSA, B);
12929 if (NestedLoopCount == 0)
12933 "omp target parallel for loop exprs were not built");
12938 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
12940 B.NumIterations, *
this, CurScope,
12948 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
12955 return llvm::any_of(
12956 Clauses, [K](
const OMPClause *
C) {
return C->getClauseKind() == K; });
12959template <
typename... Params>
12961 const Params... ClauseTypes) {
12968 if (
auto *TC = dyn_cast<OMPToClause>(
C))
12969 return llvm::all_of(TC->all_decls(), [](
ValueDecl *VD) {
12970 return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() ||
12971 (VD->isExternallyVisible() &&
12972 VD->getVisibility() != HiddenVisibility);
12974 else if (
auto *FC = dyn_cast<OMPFromClause>(
C))
12975 return llvm::all_of(FC->all_decls(), [](
ValueDecl *VD) {
12976 return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() ||
12977 (VD->isExternallyVisible() &&
12978 VD->getVisibility() != HiddenVisibility);
12992 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
12997 if (!
hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) &&
13001 Expected =
"'map' or 'use_device_ptr'";
13003 Expected =
"'map', 'use_device_ptr', or 'use_device_addr'";
13004 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13005 <<
Expected << getOpenMPDirectiveName(OMPD_target_data);
13030 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13043 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13044 <<
"'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
13067 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13080 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13081 <<
"'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
13104 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13114 if (!
hasClauses(Clauses, OMPC_to, OMPC_from)) {
13115 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
13120 Diag(StartLoc, diag::err_omp_cannot_update_with_internal_linkage);
13144 DSAStack->setParentTeamsRegionLoc(StartLoc);
13153 if (
DSAStack->isParentNowaitRegion()) {
13154 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
13157 if (
DSAStack->isParentOrderedRegion()) {
13158 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
13169 if (
DSAStack->isParentNowaitRegion()) {
13170 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
13173 if (
DSAStack->isParentOrderedRegion()) {
13174 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
13177 DSAStack->setParentCancelRegion(
true);
13184 const OMPClause *ReductionClause =
nullptr;
13185 const OMPClause *NogroupClause =
nullptr;
13187 if (
C->getClauseKind() == OMPC_reduction) {
13188 ReductionClause =
C;
13193 if (
C->getClauseKind() == OMPC_nogroup) {
13195 if (ReductionClause)
13200 if (ReductionClause && NogroupClause) {
13201 S.
Diag(ReductionClause->
getBeginLoc(), diag::err_omp_reduction_with_nogroup)
13215 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
13216 OMPLoopBasedDirective::HelperExprs B;
13219 unsigned NestedLoopCount =
13222 VarsWithImplicitDSA, B);
13223 if (NestedLoopCount == 0)
13227 "omp for loop exprs were not built");
13233 {OMPC_grainsize, OMPC_num_tasks}))
13243 NestedLoopCount, Clauses, AStmt, B,
13253 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
13254 OMPLoopBasedDirective::HelperExprs B;
13257 unsigned NestedLoopCount =
13260 VarsWithImplicitDSA, B);
13261 if (NestedLoopCount == 0)
13265 "omp for loop exprs were not built");
13270 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
13272 B.NumIterations, *
this, CurScope,
13282 {OMPC_grainsize, OMPC_num_tasks}))
13294 NestedLoopCount, Clauses, AStmt, B);
13303 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
13304 OMPLoopBasedDirective::HelperExprs B;
13307 unsigned NestedLoopCount =
13310 VarsWithImplicitDSA, B);
13311 if (NestedLoopCount == 0)
13315 "omp for loop exprs were not built");
13321 {OMPC_grainsize, OMPC_num_tasks}))
13331 NestedLoopCount, Clauses, AStmt, B,
13341 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
13342 OMPLoopBasedDirective::HelperExprs B;
13345 unsigned NestedLoopCount =
13348 VarsWithImplicitDSA, B);
13349 if (NestedLoopCount == 0)
13353 "omp for loop exprs were not built");
13359 {OMPC_grainsize, OMPC_num_tasks}))
13369 NestedLoopCount, Clauses, AStmt, B,
13379 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
13380 OMPLoopBasedDirective::HelperExprs B;
13383 unsigned NestedLoopCount =
13386 VarsWithImplicitDSA, B);
13387 if (NestedLoopCount == 0)
13391 "omp for loop exprs were not built");
13396 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
13398 B.NumIterations, *
this, CurScope,
13408 {OMPC_grainsize, OMPC_num_tasks}))
13420 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13429 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
13430 OMPLoopBasedDirective::HelperExprs B;
13433 unsigned NestedLoopCount =
13436 VarsWithImplicitDSA, B);
13437 if (NestedLoopCount == 0)
13441 "omp for loop exprs were not built");
13446 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
13448 B.NumIterations, *
this, CurScope,
13458 {OMPC_grainsize, OMPC_num_tasks}))
13470 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13479 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
13487 for (
int ThisCaptureLevel =
13489 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13499 OMPLoopBasedDirective::HelperExprs B;
13505 VarsWithImplicitDSA, B);
13506 if (NestedLoopCount == 0)
13510 "omp for loop exprs were not built");
13516 {OMPC_grainsize, OMPC_num_tasks}))
13526 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13536 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
13544 for (
int ThisCaptureLevel =
13546 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13556 OMPLoopBasedDirective::HelperExprs B;
13562 VarsWithImplicitDSA, B);
13563 if (NestedLoopCount == 0)
13567 "omp for loop exprs were not built");
13573 {OMPC_grainsize, OMPC_num_tasks}))
13583 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13593 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
13601 for (
int ThisCaptureLevel =
13603 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13613 OMPLoopBasedDirective::HelperExprs B;
13619 VarsWithImplicitDSA, B);
13620 if (NestedLoopCount == 0)
13624 "omp for loop exprs were not built");
13629 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
13631 B.NumIterations, *
this, CurScope,
13641 {OMPC_grainsize, OMPC_num_tasks}))
13653 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13662 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
13670 for (
int ThisCaptureLevel =
13672 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13682 OMPLoopBasedDirective::HelperExprs B;
13688 VarsWithImplicitDSA, B);
13689 if (NestedLoopCount == 0)
13693 "omp for loop exprs were not built");
13698 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
13700 B.NumIterations, *
this, CurScope,
13710 {OMPC_grainsize, OMPC_num_tasks}))
13722 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13731 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
13732 OMPLoopBasedDirective::HelperExprs B;
13735 unsigned NestedLoopCount =
13738 *
this, *
DSAStack, VarsWithImplicitDSA, B);
13739 if (NestedLoopCount == 0)
13743 "omp for loop exprs were not built");
13747 NestedLoopCount, Clauses, AStmt, B);
13763 for (
int ThisCaptureLevel =
13765 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13775 OMPLoopBasedDirective::HelperExprs B;
13781 VarsWithImplicitDSA, B);
13782 if (NestedLoopCount == 0)
13786 "omp for loop exprs were not built");
13790 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13807 for (
int ThisCaptureLevel =
13809 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13819 OMPLoopBasedDirective::HelperExprs B;
13825 VarsWithImplicitDSA, B);
13826 if (NestedLoopCount == 0)
13830 "omp for loop exprs were not built");
13835 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
13837 B.NumIterations, *
this, CurScope,
13848 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13865 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13875 OMPLoopBasedDirective::HelperExprs B;
13878 unsigned NestedLoopCount =
13880 nullptr , CS, *
this,
13881 *
DSAStack, VarsWithImplicitDSA, B);
13882 if (NestedLoopCount == 0)
13886 "omp for loop exprs were not built");
13891 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
13893 B.NumIterations, *
this, CurScope,
13904 NestedLoopCount, Clauses, AStmt, B);
13921 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13931 OMPLoopBasedDirective::HelperExprs B;
13938 if (NestedLoopCount == 0)
13942 "omp target parallel for simd loop exprs were not built");
13947 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
13949 B.NumIterations, *
this, CurScope,
13959 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13976 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13986 OMPLoopBasedDirective::HelperExprs B;
13989 unsigned NestedLoopCount =
13992 VarsWithImplicitDSA, B);
13993 if (NestedLoopCount == 0)
13997 "omp target simd loop exprs were not built");
14002 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14004 B.NumIterations, *
this, CurScope,
14015 NestedLoopCount, Clauses, AStmt, B);
14032 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14042 OMPLoopBasedDirective::HelperExprs B;
14045 unsigned NestedLoopCount =
14047 nullptr , CS, *
this,
14048 *
DSAStack, VarsWithImplicitDSA, B);
14049 if (NestedLoopCount == 0)
14053 "omp teams distribute loop exprs were not built");
14057 DSAStack->setParentTeamsRegionLoc(StartLoc);
14060 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14076 for (
int ThisCaptureLevel =
14078 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14088 OMPLoopBasedDirective::HelperExprs B;
14094 VarsWithImplicitDSA, B);
14096 if (NestedLoopCount == 0)
14100 "omp teams distribute simd loop exprs were not built");
14105 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14107 B.NumIterations, *
this, CurScope,
14118 DSAStack->setParentTeamsRegionLoc(StartLoc);
14121 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14138 for (
int ThisCaptureLevel =
14140 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14150 OMPLoopBasedDirective::HelperExprs B;
14156 VarsWithImplicitDSA, B);
14158 if (NestedLoopCount == 0)
14162 "omp for loop exprs were not built");
14167 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14169 B.NumIterations, *
this, CurScope,
14180 DSAStack->setParentTeamsRegionLoc(StartLoc);
14183 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14200 for (
int ThisCaptureLevel =
14202 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14212 OMPLoopBasedDirective::HelperExprs B;
14218 VarsWithImplicitDSA, B);
14220 if (NestedLoopCount == 0)
14224 "omp for loop exprs were not built");
14228 DSAStack->setParentTeamsRegionLoc(StartLoc);
14231 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14251 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14279 for (
int ThisCaptureLevel =
14281 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14291 OMPLoopBasedDirective::HelperExprs B;
14297 VarsWithImplicitDSA, B);
14298 if (NestedLoopCount == 0)
14302 "omp target teams distribute loop exprs were not built");
14306 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14322 for (
int ThisCaptureLevel =
14324 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14334 OMPLoopBasedDirective::HelperExprs B;
14340 VarsWithImplicitDSA, B);
14341 if (NestedLoopCount == 0)
14345 "omp target teams distribute parallel for loop exprs were not built");
14350 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14352 B.NumIterations, *
this, CurScope,
14360 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14378 OMPD_target_teams_distribute_parallel_for_simd);
14379 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14389 OMPLoopBasedDirective::HelperExprs B;
14392 unsigned NestedLoopCount =
14395 nullptr , CS, *
this,
14396 *
DSAStack, VarsWithImplicitDSA, B);
14397 if (NestedLoopCount == 0)
14401 "omp target teams distribute parallel for simd loop exprs were not "
14407 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14409 B.NumIterations, *
this, CurScope,
14420 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14436 for (
int ThisCaptureLevel =
14438 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14448 OMPLoopBasedDirective::HelperExprs B;
14454 VarsWithImplicitDSA, B);
14455 if (NestedLoopCount == 0)
14459 "omp target teams distribute simd loop exprs were not built");
14464 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14466 B.NumIterations, *
this, CurScope,
14477 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14480bool Sema::checkTransformableLoopNest(
14486 OriginalInits.emplace_back();
14487 bool Result = OMPLoopBasedDirective::doForAllLoops(
14489 [
this, &LoopHelpers, &Body, &OriginalInits, Kind](
unsigned Cnt,
14491 VarsWithInheritedDSAType TmpDSA;
14492 unsigned SingleNumLoops =
14493 checkOpenMPLoop(Kind, nullptr, nullptr, CurStmt, *this, *DSAStack,
14494 TmpDSA, LoopHelpers[Cnt]);
14495 if (SingleNumLoops == 0)
14497 assert(SingleNumLoops == 1 &&
"Expect single loop iteration space");
14498 if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
14499 OriginalInits.back().push_back(For->getInit());
14500 Body = For->getBody();
14502 assert(isa<CXXForRangeStmt>(CurStmt) &&
14503 "Expected canonical for or range-based for loops.");
14504 auto *CXXFor = cast<CXXForRangeStmt>(CurStmt);
14505 OriginalInits.back().push_back(CXXFor->getBeginStmt());
14506 Body = CXXFor->getBody();
14508 OriginalInits.emplace_back();
14511 [&OriginalInits](OMPLoopBasedDirective *Transform) {
14512 Stmt *DependentPreInits;
14513 if (
auto *Dir = dyn_cast<OMPTileDirective>(Transform))
14514 DependentPreInits = Dir->getPreInits();
14515 else if (
auto *Dir = dyn_cast<OMPUnrollDirective>(Transform))
14516 DependentPreInits = Dir->getPreInits();
14518 llvm_unreachable(
"Unhandled loop transformation");
14519 if (!DependentPreInits)
14521 llvm::append_range(OriginalInits.back(),
14522 cast<DeclStmt>(DependentPreInits)->getDeclGroup());
14524 assert(OriginalInits.back().empty() &&
"No preinit after innermost loop");
14525 OriginalInits.pop_back();
14532 auto SizesClauses =
14533 OMPExecutableDirective::getClausesOfKind<OMPSizesClause>(Clauses);
14534 if (SizesClauses.empty()) {
14547 Stmt *Body =
nullptr;
14550 if (!checkTransformableLoopNest(OMPD_tile, AStmt, NumLoops, LoopHelpers, Body,
14557 NumLoops, AStmt,
nullptr,
nullptr);
14564 FloorIndVars.resize(NumLoops);
14565 TileIndVars.resize(NumLoops);
14566 for (
unsigned I = 0; I < NumLoops; ++I) {
14567 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
14569 assert(LoopHelper.Counters.size() == 1 &&
14570 "Expect single-dimensional loop iteration space");
14572 std::string OrigVarName = OrigCntVar->getNameInfo().getAsString();
14578 std::string FloorCntName =
14579 (Twine(
".floor_") + llvm::utostr(I) +
".iv." + OrigVarName).str();
14581 buildVarDecl(*
this, {}, CntTy, FloorCntName,
nullptr, OrigCntVar);
14582 FloorIndVars[I] = FloorCntDecl;
14587 std::string TileCntName =
14588 (Twine(
".tile_") + llvm::utostr(I) +
".iv." + OrigVarName).str();
14595 TileIndVars[I] = TileCntDecl;
14597 for (
auto &
P : OriginalInits[I]) {
14598 if (
auto *D =
P.dyn_cast<
Decl *>())
14599 PreInits.push_back(D);
14600 else if (
auto *PI = dyn_cast_or_null<DeclStmt>(
P.dyn_cast<
Stmt *>()))
14601 PreInits.append(PI->decl_begin(), PI->decl_end());
14603 if (
auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits))
14604 PreInits.append(PI->decl_begin(), PI->decl_end());
14606 for (
Expr *CounterRef : LoopHelper.Counters) {
14608 if (isa<OMPCapturedExprDecl>(CounterDecl))
14609 PreInits.push_back(CounterDecl);
14614 Stmt *Inner = Body;
14617 for (
int I = NumLoops - 1; I >= 0; --I) {
14618 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
14619 Expr *NumIterations = LoopHelper.NumIterations;
14621 QualType CntTy = OrigCntVar->getType();
14627 OrigCntVar->getExprLoc());
14629 OrigCntVar->getExprLoc());
14634 Decl *CounterDecl = TileIndVars[I];
14637 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
14644 BO_Add, FloorIV, DimTileSize);
14648 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT,
14649 NumIterations, EndOfTile.
get());
14653 LoopHelper.Cond->getBeginLoc(), LoopHelper.Cond->getEndLoc(),
14654 IsPartialTile.
get(), NumIterations, EndOfTile.
get());
14655 if (!MinTileAndIterSpace.
isUsable())
14658 BO_LT, TileIV, MinTileAndIterSpace.
get());
14664 BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(), UO_PreInc, TileIV);
14682 BodyParts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
14683 BodyParts.push_back(Inner);
14685 Inner->getBeginLoc(), Inner->getEndLoc());
14688 IncrStmt.
get(), Inner, LoopHelper.Init->getBeginLoc(),
14689 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
14693 for (
int I = NumLoops - 1; I >= 0; --I) {
14694 auto &LoopHelper = LoopHelpers[I];
14695 Expr *NumIterations = LoopHelper.NumIterations;
14710 Decl *CounterDecl = FloorIndVars[I];
14719 BO_LT, FloorIV, NumIterations);
14725 BO_AddAssign, FloorIV, DimTileSize);
14731 IncrStmt.
get(), Inner, LoopHelper.Init->getBeginLoc(),
14732 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
14752 OMPExecutableDirective::getSingleClause<OMPFullClause>(Clauses);
14754 OMPExecutableDirective::getSingleClause<OMPPartialClause>(Clauses);
14755 assert(!(FullClause && PartialClause) &&
14756 "mutual exclusivity must have been checked before");
14758 constexpr unsigned NumLoops = 1;
14759 Stmt *Body =
nullptr;
14764 if (!checkTransformableLoopNest(OMPD_unroll, AStmt, NumLoops, LoopHelpers,
14765 Body, OriginalInits))
14768 unsigned NumGeneratedLoops = PartialClause ? 1 : 0;
14773 NumGeneratedLoops,
nullptr,
nullptr);
14775 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front();
14778 if (!VerifyPositiveIntegerConstantInClause(
14779 LoopHelper.NumIterations, OMPC_full,
false,
14782 Diag(AStmt->
getBeginLoc(), diag::err_omp_unroll_full_variable_trip_count);
14784 <<
"#pragma omp unroll full";
14792 if (NumGeneratedLoops == 0)
14794 NumGeneratedLoops,
nullptr,
nullptr);
14840 assert(OriginalInits.size() == 1 &&
14841 "Expecting a single-dimensional loop iteration space");
14842 for (
auto &
P : OriginalInits[0]) {
14843 if (
auto *D =
P.dyn_cast<
Decl *>())
14844 PreInits.push_back(D);
14845 else if (
auto *PI = dyn_cast_or_null<DeclStmt>(
P.dyn_cast<
Stmt *>()))
14846 PreInits.append(PI->decl_begin(), PI->decl_end());
14848 if (
auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits))
14849 PreInits.append(PI->decl_begin(), PI->decl_end());
14851 for (
Expr *CounterRef : LoopHelper.Counters) {
14853 if (isa<OMPCapturedExprDecl>(CounterDecl))
14854 PreInits.push_back(CounterDecl);
14858 QualType IVTy = IterationVarRef->getType();
14859 assert(LoopHelper.Counters.size() == 1 &&
14860 "Expecting a single-dimensional loop iteration space");
14867 Factor = FactorVal->getIntegerConstantExpr(
Context)->getZExtValue();
14868 FactorLoc = FactorVal->getExprLoc();
14873 assert(Factor > 0 &&
"Expected positive unroll factor");
14874 auto MakeFactorExpr = [
this, Factor, IVTy, FactorLoc]() {
14886 std::string OrigVarName = OrigVar->getNameInfo().getAsString();
14887 std::string OuterIVName = (Twine(
".unrolled.iv.") + OrigVarName).str();
14888 std::string InnerIVName = (Twine(
".unroll_inner.iv.") + OrigVarName).str();
14889 std::string InnerTripCountName =
14890 (Twine(
".unroll_inner.tripcount.") + OrigVarName).str();
14894 buildVarDecl(*
this, {}, IVTy, OuterIVName,
nullptr, OrigVar);
14895 auto MakeOuterRef = [
this, OuterIVDecl, IVTy, OrigVarLoc]() {
14901 auto *InnerIVDecl =
cast<VarDecl>(IterationVarRef->getDecl());
14903 auto MakeInnerRef = [
this, InnerIVDecl, IVTy, OrigVarLoc]() {
14909 CaptureVars CopyTransformer(*
this);
14910 auto MakeNumIterations = [&CopyTransformer, &LoopHelper]() ->
Expr * {
14912 CopyTransformer.TransformExpr(LoopHelper.NumIterations));
14931 BO_Add, MakeOuterRef(), MakeFactorExpr());
14935 BO_LT, MakeInnerRef(), EndOfTile.
get());
14939 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeInnerRef(),
14940 MakeNumIterations());
14944 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LAnd,
14945 InnerCond1.
get(), InnerCond2.
get());
14951 UO_PreInc, MakeInnerRef());
14957 InnerBodyStmts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
14958 InnerBodyStmts.push_back(Body);
14965 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
14979 LoopHintAttr *UnrollHintAttr =
14980 LoopHintAttr::CreateImplicit(
Context, LoopHintAttr::UnrollCount,
14981 LoopHintAttr::Numeric, MakeFactorExpr());
14996 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeOuterRef(),
14997 MakeNumIterations());
15003 BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(), BO_AddAssign,
15004 MakeOuterRef(), MakeFactorExpr());
15012 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
15015 NumGeneratedLoops, OuterFor,
15028 case OMPC_num_threads:
15037 case OMPC_allocator:
15040 case OMPC_collapse:
15046 case OMPC_num_teams:
15049 case OMPC_thread_limit:
15052 case OMPC_priority:
15055 case OMPC_grainsize:
15058 case OMPC_num_tasks:
15070 case OMPC_novariants:
15073 case OMPC_nocontext:
15088 case OMPC_proc_bind:
15089 case OMPC_schedule:
15091 case OMPC_firstprivate:
15092 case OMPC_lastprivate:
15094 case OMPC_reduction:
15095 case OMPC_task_reduction:
15096 case OMPC_in_reduction:
15100 case OMPC_copyprivate:
15103 case OMPC_mergeable:
15104 case OMPC_threadprivate:
15106 case OMPC_allocate:
15123 case OMPC_dist_schedule:
15124 case OMPC_defaultmap:
15129 case OMPC_use_device_ptr:
15130 case OMPC_use_device_addr:
15131 case OMPC_is_device_ptr:
15132 case OMPC_unified_address:
15133 case OMPC_unified_shared_memory:
15134 case OMPC_reverse_offload:
15135 case OMPC_dynamic_allocators:
15136 case OMPC_atomic_default_mem_order:
15137 case OMPC_device_type:
15139 case OMPC_nontemporal:
15142 case OMPC_inclusive:
15143 case OMPC_exclusive:
15144 case OMPC_uses_allocators:
15145 case OMPC_affinity:
15149 llvm_unreachable(
"Clause is not allowed.");
15166 case OMPD_target_parallel_for_simd:
15167 if (OpenMPVersion >= 50 &&
15168 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
15169 CaptureRegion = OMPD_parallel;
15173 case OMPD_target_parallel:
15174 case OMPD_target_parallel_for:
15175 case OMPD_target_parallel_loop:
15178 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
15179 CaptureRegion = OMPD_target;
15181 case OMPD_target_teams_distribute_parallel_for_simd:
15182 if (OpenMPVersion >= 50 &&
15183 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
15184 CaptureRegion = OMPD_parallel;
15188 case OMPD_target_teams_distribute_parallel_for:
15191 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
15192 CaptureRegion = OMPD_teams;
15194 case OMPD_teams_distribute_parallel_for_simd:
15195 if (OpenMPVersion >= 50 &&
15196 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
15197 CaptureRegion = OMPD_parallel;
15201 case OMPD_teams_distribute_parallel_for:
15202 CaptureRegion = OMPD_teams;
15204 case OMPD_target_update:
15205 case OMPD_target_enter_data:
15206 case OMPD_target_exit_data:
15207 CaptureRegion = OMPD_task;
15209 case OMPD_parallel_masked_taskloop:
15210 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
15211 CaptureRegion = OMPD_parallel;
15213 case OMPD_parallel_master_taskloop:
15214 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
15215 CaptureRegion = OMPD_parallel;
15217 case OMPD_parallel_masked_taskloop_simd:
15218 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
15219 NameModifier == OMPD_taskloop) {
15220 CaptureRegion = OMPD_parallel;
15223 if (OpenMPVersion <= 45)
15225 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15226 CaptureRegion = OMPD_taskloop;
15228 case OMPD_parallel_master_taskloop_simd:
15229 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
15230 NameModifier == OMPD_taskloop) {
15231 CaptureRegion = OMPD_parallel;
15234 if (OpenMPVersion <= 45)
15236 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15237 CaptureRegion = OMPD_taskloop;
15239 case OMPD_parallel_for_simd:
15240 if (OpenMPVersion <= 45)
15242 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15243 CaptureRegion = OMPD_parallel;
15245 case OMPD_taskloop_simd:
15246 case OMPD_master_taskloop_simd:
15247 case OMPD_masked_taskloop_simd:
15248 if (OpenMPVersion <= 45)
15250 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15251 CaptureRegion = OMPD_taskloop;
15253 case OMPD_distribute_parallel_for_simd:
15254 if (OpenMPVersion <= 45)
15256 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15257 CaptureRegion = OMPD_parallel;
15259 case OMPD_target_simd:
15260 if (OpenMPVersion >= 50 &&
15261 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
15262 CaptureRegion = OMPD_target;
15264 case OMPD_teams_distribute_simd:
15265 case OMPD_target_teams_distribute_simd:
15266 if (OpenMPVersion >= 50 &&
15267 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
15268 CaptureRegion = OMPD_teams;
15271 case OMPD_parallel:
15272 case OMPD_parallel_master:
15273 case OMPD_parallel_masked:
15274 case OMPD_parallel_sections:
15275 case OMPD_parallel_for:
15276 case OMPD_parallel_loop:
15278 case OMPD_target_teams:
15279 case OMPD_target_teams_distribute:
15280 case OMPD_target_teams_loop:
15281 case OMPD_distribute_parallel_for:
15283 case OMPD_taskloop:
15284 case OMPD_master_taskloop:
15285 case OMPD_masked_taskloop:
15286 case OMPD_target_data:
15288 case OMPD_for_simd:
15289 case OMPD_distribute_simd:
15292 case OMPD_threadprivate:
15293 case OMPD_allocate:
15294 case OMPD_taskyield:
15296 case OMPD_taskwait:
15297 case OMPD_cancellation_point:
15301 case OMPD_declare_reduction:
15302 case OMPD_declare_mapper:
15303 case OMPD_declare_simd:
15304 case OMPD_declare_variant:
15305 case OMPD_begin_declare_variant:
15306 case OMPD_end_declare_variant:
15307 case OMPD_declare_target:
15308 case OMPD_end_declare_target:
15310 case OMPD_teams_loop:
15315 case OMPD_sections:
15320 case OMPD_critical:
15321 case OMPD_taskgroup:
15322 case OMPD_distribute:
15325 case OMPD_teams_distribute:
15326 case OMPD_requires:
15327 case OMPD_metadirective:
15328 llvm_unreachable(
"Unexpected OpenMP directive with if-clause");
15331 llvm_unreachable(
"Unknown OpenMP directive");
15334 case OMPC_num_threads:
15336 case OMPD_target_parallel:
15337 case OMPD_target_parallel_for:
15338 case OMPD_target_parallel_for_simd:
15339 case OMPD_target_parallel_loop:
15340 CaptureRegion = OMPD_target;
15342 case OMPD_teams_distribute_parallel_for:
15343 case OMPD_teams_distribute_parallel_for_simd:
15344 case OMPD_target_teams_distribute_parallel_for:
15345 case OMPD_target_teams_distribute_parallel_for_simd:
15346 CaptureRegion = OMPD_teams;
15348 case OMPD_parallel:
15349 case OMPD_parallel_master:
15350 case OMPD_parallel_masked:
15351 case OMPD_parallel_sections:
15352 case OMPD_parallel_for:
15353 case OMPD_parallel_for_simd:
15354 case OMPD_parallel_loop:
15355 case OMPD_distribute_parallel_for:
15356 case OMPD_distribute_parallel_for_simd:
15357 case OMPD_parallel_master_taskloop:
15358 case OMPD_parallel_masked_taskloop:
15359 case OMPD_parallel_master_taskloop_simd:
15360 case OMPD_parallel_masked_taskloop_simd:
15363 case OMPD_target_data:
15364 case OMPD_target_enter_data:
15365 case OMPD_target_exit_data:
15366 case OMPD_target_update:
15368 case OMPD_target_simd:
15369 case OMPD_target_teams:
15370 case OMPD_target_teams_distribute:
15371 case OMPD_target_teams_distribute_simd:
15374 case OMPD_taskloop:
15375 case OMPD_taskloop_simd:
15376 case OMPD_master_taskloop:
15377 case OMPD_masked_taskloop:
15378 case OMPD_master_taskloop_simd:
15379 case OMPD_masked_taskloop_simd:
15380 case OMPD_threadprivate:
15381 case OMPD_allocate:
15382 case OMPD_taskyield:
15384 case OMPD_taskwait:
15385 case OMPD_cancellation_point:
15389 case OMPD_declare_reduction:
15390 case OMPD_declare_mapper:
15391 case OMPD_declare_simd:
15392 case OMPD_declare_variant:
15393 case OMPD_begin_declare_variant:
15394 case OMPD_end_declare_variant:
15395 case OMPD_declare_target:
15396 case OMPD_end_declare_target:
15398 case OMPD_teams_loop:
15399 case OMPD_target_teams_loop:
15405 case OMPD_for_simd:
15406 case OMPD_sections:
15411 case OMPD_critical:
15412 case OMPD_taskgroup:
15413 case OMPD_distribute:
15416 case OMPD_distribute_simd:
15417 case OMPD_teams_distribute:
15418 case OMPD_teams_distribute_simd:
15419 case OMPD_requires:
15420 case OMPD_metadirective:
15421 llvm_unreachable(
"Unexpected OpenMP directive with num_threads-clause");
15424 llvm_unreachable(
"Unknown OpenMP directive");
15427 case OMPC_num_teams:
15429 case OMPD_target_teams:
15430 case OMPD_target_teams_distribute:
15431 case OMPD_target_teams_distribute_simd:
15432 case OMPD_target_teams_distribute_parallel_for:
15433 case OMPD_target_teams_distribute_parallel_for_simd:
15434 case OMPD_target_teams_loop:
15435 CaptureRegion = OMPD_target;
15437 case OMPD_teams_distribute_parallel_for:
15438 case OMPD_teams_distribute_parallel_for_simd:
15440 case OMPD_teams_distribute:
15441 case OMPD_teams_distribute_simd:
15442 case OMPD_teams_loop:
15445 case OMPD_distribute_parallel_for:
15446 case OMPD_distribute_parallel_for_simd:
15448 case OMPD_taskloop:
15449 case OMPD_taskloop_simd:
15450 case OMPD_master_taskloop:
15451 case OMPD_masked_taskloop:
15452 case OMPD_master_taskloop_simd:
15453 case OMPD_masked_taskloop_simd:
15454 case OMPD_parallel_master_taskloop:
15455 case OMPD_parallel_masked_taskloop:
15456 case OMPD_parallel_master_taskloop_simd:
15457 case OMPD_parallel_masked_taskloop_simd:
15458 case OMPD_target_data:
15459 case OMPD_target_enter_data:
15460 case OMPD_target_exit_data:
15461 case OMPD_target_update:
15463 case OMPD_parallel:
15464 case OMPD_parallel_master:
15465 case OMPD_parallel_masked:
15466 case OMPD_parallel_sections:
15467 case OMPD_parallel_for:
15468 case OMPD_parallel_for_simd:
15469 case OMPD_parallel_loop:
15471 case OMPD_target_simd:
15472 case OMPD_target_parallel:
15473 case OMPD_target_parallel_for:
15474 case OMPD_target_parallel_for_simd:
15475 case OMPD_target_parallel_loop:
15476 case OMPD_threadprivate:
15477 case OMPD_allocate:
15478 case OMPD_taskyield:
15480 case OMPD_taskwait:
15481 case OMPD_cancellation_point:
15485 case OMPD_declare_reduction:
15486 case OMPD_declare_mapper:
15487 case OMPD_declare_simd:
15488 case OMPD_declare_variant:
15489 case OMPD_begin_declare_variant:
15490 case OMPD_end_declare_variant:
15491 case OMPD_declare_target:
15492 case OMPD_end_declare_target:
15498 case OMPD_for_simd:
15499 case OMPD_sections:
15504 case OMPD_critical:
15505 case OMPD_taskgroup:
15506 case OMPD_distribute:
15509 case OMPD_distribute_simd:
15510 case OMPD_requires:
15511 case OMPD_metadirective:
15512 llvm_unreachable(
"Unexpected OpenMP directive with num_teams-clause");
15515 llvm_unreachable(
"Unknown OpenMP directive");
15518 case OMPC_thread_limit:
15520 case OMPD_target_teams:
15521 case OMPD_target_teams_distribute:
15522 case OMPD_target_teams_distribute_simd:
15523 case OMPD_target_teams_distribute_parallel_for:
15524 case OMPD_target_teams_distribute_parallel_for_simd:
15525 case OMPD_target_teams_loop:
15526 CaptureRegion = OMPD_target;
15528 case OMPD_teams_distribute_parallel_for:
15529 case OMPD_teams_distribute_parallel_for_simd:
15531 case OMPD_teams_distribute:
15532 case OMPD_teams_distribute_simd:
15533 case OMPD_teams_loop:
15536 case OMPD_distribute_parallel_for:
15537 case OMPD_distribute_parallel_for_simd:
15539 case OMPD_taskloop:
15540 case OMPD_taskloop_simd:
15541 case OMPD_master_taskloop:
15542 case OMPD_masked_taskloop:
15543 case OMPD_master_taskloop_simd:
15544 case OMPD_masked_taskloop_simd:
15545 case OMPD_parallel_master_taskloop:
15546 case OMPD_parallel_masked_taskloop:
15547 case OMPD_parallel_master_taskloop_simd:
15548 case OMPD_parallel_masked_taskloop_simd:
15549 case OMPD_target_data:
15550 case OMPD_target_enter_data:
15551 case OMPD_target_exit_data:
15552 case OMPD_target_update:
15554 case OMPD_parallel:
15555 case OMPD_parallel_master:
15556 case OMPD_parallel_masked:
15557 case OMPD_parallel_sections:
15558 case OMPD_parallel_for:
15559 case OMPD_parallel_for_simd:
15560 case OMPD_parallel_loop:
15562 case OMPD_target_simd:
15563 case OMPD_target_parallel:
15564 case OMPD_target_parallel_for:
15565 case OMPD_target_parallel_for_simd:
15566 case OMPD_target_parallel_loop:
15567 case OMPD_threadprivate:
15568 case OMPD_allocate:
15569 case OMPD_taskyield:
15571 case OMPD_taskwait:
15572 case OMPD_cancellation_point:
15576 case OMPD_declare_reduction:
15577 case OMPD_declare_mapper:
15578 case OMPD_declare_simd:
15579 case OMPD_declare_variant:
15580 case OMPD_begin_declare_variant:
15581 case OMPD_end_declare_variant:
15582 case OMPD_declare_target:
15583 case OMPD_end_declare_target:
15589 case OMPD_for_simd:
15590 case OMPD_sections:
15595 case OMPD_critical:
15596 case OMPD_taskgroup:
15597 case OMPD_distribute:
15600 case OMPD_distribute_simd:
15601 case OMPD_requires:
15602 case OMPD_metadirective:
15603 llvm_unreachable(
"Unexpected OpenMP directive with thread_limit-clause");
15606 llvm_unreachable(
"Unknown OpenMP directive");
15609 case OMPC_schedule:
15611 case OMPD_parallel_for:
15612 case OMPD_parallel_for_simd:
15613 case OMPD_distribute_parallel_for:
15614 case OMPD_distribute_parallel_for_simd:
15615 case OMPD_teams_distribute_parallel_for:
15616 case OMPD_teams_distribute_parallel_for_simd:
15617 case OMPD_target_parallel_for:
15618 case OMPD_target_parallel_for_simd:
15619 case OMPD_target_teams_distribute_parallel_for:
15620 case OMPD_target_teams_distribute_parallel_for_simd:
15621 CaptureRegion = OMPD_parallel;
15624 case OMPD_for_simd:
15628 case OMPD_taskloop:
15629 case OMPD_taskloop_simd:
15630 case OMPD_master_taskloop:
15631 case OMPD_masked_taskloop:
15632 case OMPD_master_taskloop_simd:
15633 case OMPD_masked_taskloop_simd:
15634 case OMPD_parallel_master_taskloop:
15635 case OMPD_parallel_masked_taskloop:
15636 case OMPD_parallel_master_taskloop_simd:
15637 case OMPD_parallel_masked_taskloop_simd:
15638 case OMPD_target_data:
15639 case OMPD_target_enter_data:
15640 case OMPD_target_exit_data:
15641 case OMPD_target_update:
15643 case OMPD_teams_distribute:
15644 case OMPD_teams_distribute_simd:
15645 case OMPD_target_teams_distribute:
15646 case OMPD_target_teams_distribute_simd:
15648 case OMPD_target_simd:
15649 case OMPD_target_parallel:
15651 case OMPD_parallel:
15652 case OMPD_parallel_master:
15653 case OMPD_parallel_masked:
15654 case OMPD_parallel_sections:
15655 case OMPD_threadprivate:
15656 case OMPD_allocate:
15657 case OMPD_taskyield:
15659 case OMPD_taskwait:
15660 case OMPD_cancellation_point:
15664 case OMPD_declare_reduction:
15665 case OMPD_declare_mapper:
15666 case OMPD_declare_simd:
15667 case OMPD_declare_variant:
15668 case OMPD_begin_declare_variant:
15669 case OMPD_end_declare_variant:
15670 case OMPD_declare_target:
15671 case OMPD_end_declare_target:
15673 case OMPD_teams_loop:
15674 case OMPD_target_teams_loop:
15675 case OMPD_parallel_loop:
15676 case OMPD_target_parallel_loop:
15680 case OMPD_sections:
15685 case OMPD_critical:
15686 case OMPD_taskgroup:
15687 case OMPD_distribute:
15690 case OMPD_distribute_simd:
15691 case OMPD_target_teams:
15692 case OMPD_requires:
15693 case OMPD_metadirective:
15694 llvm_unreachable(
"Unexpected OpenMP directive with schedule clause");
15697 llvm_unreachable(
"Unknown OpenMP directive");
15700 case OMPC_dist_schedule:
15702 case OMPD_teams_distribute_parallel_for:
15703 case OMPD_teams_distribute_parallel_for_simd:
15704 case OMPD_teams_distribute:
15705 case OMPD_teams_distribute_simd:
15706 case OMPD_target_teams_distribute_parallel_for:
15707 case OMPD_target_teams_distribute_parallel_for_simd:
15708 case OMPD_target_teams_distribute:
15709 case OMPD_target_teams_distribute_simd:
15710 CaptureRegion = OMPD_teams;
15712 case OMPD_distribute_parallel_for:
15713 case OMPD_distribute_parallel_for_simd:
15714 case OMPD_distribute:
15715 case OMPD_distribute_simd:
15718 case OMPD_parallel_for:
15719 case OMPD_parallel_for_simd:
15720 case OMPD_target_parallel_for_simd:
15721 case OMPD_target_parallel_for:
15723 case OMPD_taskloop:
15724 case OMPD_taskloop_simd:
15725 case OMPD_master_taskloop:
15726 case OMPD_masked_taskloop:
15727 case OMPD_master_taskloop_simd:
15728 case OMPD_masked_taskloop_simd:
15729 case OMPD_parallel_master_taskloop:
15730 case OMPD_parallel_masked_taskloop:
15731 case OMPD_parallel_master_taskloop_simd:
15732 case OMPD_parallel_masked_taskloop_simd:
15733 case OMPD_target_data:
15734 case OMPD_target_enter_data:
15735 case OMPD_target_exit_data:
15736 case OMPD_target_update:
15739 case OMPD_target_simd:
15740 case OMPD_target_parallel:
15742 case OMPD_parallel:
15743 case OMPD_parallel_master:
15744 case OMPD_parallel_masked:
15745 case OMPD_parallel_sections:
15746 case OMPD_threadprivate:
15747 case OMPD_allocate:
15748 case OMPD_taskyield:
15750 case OMPD_taskwait:
15751 case OMPD_cancellation_point:
15755 case OMPD_declare_reduction:
15756 case OMPD_declare_mapper:
15757 case OMPD_declare_simd:
15758 case OMPD_declare_variant:
15759 case OMPD_begin_declare_variant:
15760 case OMPD_end_declare_variant:
15761 case OMPD_declare_target:
15762 case OMPD_end_declare_target:
15764 case OMPD_teams_loop:
15765 case OMPD_target_teams_loop:
15766 case OMPD_parallel_loop:
15767 case OMPD_target_parallel_loop:
15772 case OMPD_for_simd:
15773 case OMPD_sections:
15778 case OMPD_critical:
15779 case OMPD_taskgroup:
15782 case OMPD_target_teams:
15783 case OMPD_requires:
15784 case OMPD_metadirective:
15785 llvm_unreachable(
"Unexpected OpenMP directive with dist_schedule clause");
15788 llvm_unreachable(
"Unknown OpenMP directive");
15793 case OMPD_target_update:
15794 case OMPD_target_enter_data:
15795 case OMPD_target_exit_data:
15797 case OMPD_target_simd:
15798 case OMPD_target_teams:
15799 case OMPD_target_parallel:
15800 case OMPD_target_teams_distribute:
15801 case OMPD_target_teams_distribute_simd:
15802 case OMPD_target_parallel_for:
15803 case OMPD_target_parallel_for_simd:
15804 case OMPD_target_parallel_loop:
15805 case OMPD_target_teams_distribute_parallel_for:
15806 case OMPD_target_teams_distribute_parallel_for_simd:
15807 case OMPD_target_teams_loop:
15808 case OMPD_dispatch:
15809 CaptureRegion = OMPD_task;
15811 case OMPD_target_data:
15815 case OMPD_teams_distribute_parallel_for:
15816 case OMPD_teams_distribute_parallel_for_simd:
15818 case OMPD_teams_distribute:
15819 case OMPD_teams_distribute_simd:
15820 case OMPD_distribute_parallel_for:
15821 case OMPD_distribute_parallel_for_simd:
15823 case OMPD_taskloop:
15824 case OMPD_taskloop_simd:
15825 case OMPD_master_taskloop:
15826 case OMPD_masked_taskloop:
15827 case OMPD_master_taskloop_simd:
15828 case OMPD_masked_taskloop_simd:
15829 case OMPD_parallel_master_taskloop:
15830 case OMPD_parallel_masked_taskloop:
15831 case OMPD_parallel_master_taskloop_simd:
15832 case OMPD_parallel_masked_taskloop_simd:
15834 case OMPD_parallel:
15835 case OMPD_parallel_master:
15836 case OMPD_parallel_masked:
15837 case OMPD_parallel_sections:
15838 case OMPD_parallel_for:
15839 case OMPD_parallel_for_simd:
15840 case OMPD_threadprivate:
15841 case OMPD_allocate:
15842 case OMPD_taskyield:
15844 case OMPD_taskwait:
15845 case OMPD_cancellation_point:
15849 case OMPD_declare_reduction:
15850 case OMPD_declare_mapper:
15851 case OMPD_declare_simd:
15852 case OMPD_declare_variant:
15853 case OMPD_begin_declare_variant:
15854 case OMPD_end_declare_variant:
15855 case OMPD_declare_target:
15856 case OMPD_end_declare_target:
15858 case OMPD_teams_loop:
15859 case OMPD_parallel_loop:
15864 case OMPD_for_simd:
15865 case OMPD_sections:
15870 case OMPD_critical:
15871 case OMPD_taskgroup:
15872 case OMPD_distribute:
15875 case OMPD_distribute_simd:
15876 case OMPD_requires:
15877 case OMPD_metadirective:
15878 llvm_unreachable(
"Unexpected OpenMP directive with device-clause");
15881 llvm_unreachable(
"Unknown OpenMP directive");
15884 case OMPC_grainsize:
15885 case OMPC_num_tasks:
15887 case OMPC_priority:
15890 case OMPD_taskloop:
15891 case OMPD_taskloop_simd:
15892 case OMPD_master_taskloop:
15893 case OMPD_masked_taskloop:
15894 case OMPD_master_taskloop_simd:
15895 case OMPD_masked_taskloop_simd:
15897 case OMPD_parallel_masked_taskloop:
15898 case OMPD_parallel_masked_taskloop_simd:
15899 case OMPD_parallel_master_taskloop:
15900 case OMPD_parallel_master_taskloop_simd:
15901 CaptureRegion = OMPD_parallel;
15903 case OMPD_target_update:
15904 case OMPD_target_enter_data:
15905 case OMPD_target_exit_data:
15907 case OMPD_target_simd:
15908 case OMPD_target_teams:
15909 case OMPD_target_parallel:
15910 case OMPD_target_teams_distribute:
15911 case OMPD_target_teams_distribute_simd:
15912 case OMPD_target_parallel_for:
15913 case OMPD_target_parallel_for_simd:
15914 case OMPD_target_teams_distribute_parallel_for:
15915 case OMPD_target_teams_distribute_parallel_for_simd:
15916 case OMPD_target_data:
15917 case OMPD_teams_distribute_parallel_for:
15918 case OMPD_teams_distribute_parallel_for_simd:
15920 case OMPD_teams_distribute:
15921 case OMPD_teams_distribute_simd:
15922 case OMPD_distribute_parallel_for:
15923 case OMPD_distribute_parallel_for_simd:
15925 case OMPD_parallel:
15926 case OMPD_parallel_master:
15927 case OMPD_parallel_masked:
15928 case OMPD_parallel_sections:
15929 case OMPD_parallel_for:
15930 case OMPD_parallel_for_simd:
15931 case OMPD_threadprivate:
15932 case OMPD_allocate:
15933 case OMPD_taskyield:
15935 case OMPD_taskwait:
15936 case OMPD_cancellation_point:
15940 case OMPD_declare_reduction:
15941 case OMPD_declare_mapper:
15942 case OMPD_declare_simd:
15943 case OMPD_declare_variant:
15944 case OMPD_begin_declare_variant:
15945 case OMPD_end_declare_variant:
15946 case OMPD_declare_target:
15947 case OMPD_end_declare_target:
15949 case OMPD_teams_loop:
15950 case OMPD_target_teams_loop:
15951 case OMPD_parallel_loop:
15952 case OMPD_target_parallel_loop:
15957 case OMPD_for_simd:
15958 case OMPD_sections:
15963 case OMPD_critical:
15964 case OMPD_taskgroup:
15965 case OMPD_distribute:
15968 case OMPD_distribute_simd:
15969 case OMPD_requires:
15970 case OMPD_metadirective:
15971 llvm_unreachable(
"Unexpected OpenMP directive with grainsize-clause");
15974 llvm_unreachable(
"Unknown OpenMP directive");
15977 case OMPC_novariants:
15978 case OMPC_nocontext:
15980 case OMPD_dispatch:
15981 CaptureRegion = OMPD_task;
15984 llvm_unreachable(
"Unexpected OpenMP directive");
15991 if (DKind == OMPD_metadirective) {
15992 CaptureRegion = OMPD_metadirective;
15993 }
else if (DKind == OMPD_unknown) {
15994 llvm_unreachable(
"Unknown OpenMP directive");
15996 llvm_unreachable(
"Unexpected OpenMP directive with when clause");
15999 case OMPC_firstprivate:
16000 case OMPC_lastprivate:
16001 case OMPC_reduction:
16002 case OMPC_task_reduction:
16003 case OMPC_in_reduction:
16006 case OMPC_proc_bind:
16010 case OMPC_allocator:
16011 case OMPC_collapse:
16016 case OMPC_copyprivate:
16020 case OMPC_mergeable:
16021 case OMPC_threadprivate:
16022 case OMPC_allocate:
16041 case OMPC_defaultmap:
16046 case OMPC_use_device_ptr:
16047 case OMPC_use_device_addr:
16048 case OMPC_is_device_ptr:
16049 case OMPC_unified_address:
16050 case OMPC_unified_shared_memory:
16051 case OMPC_reverse_offload:
16052 case OMPC_dynamic_allocators:
16053 case OMPC_atomic_default_mem_order:
16054 case OMPC_device_type:
16056 case OMPC_nontemporal:
16060 case OMPC_inclusive:
16061 case OMPC_exclusive:
16062 case OMPC_uses_allocators:
16063 case OMPC_affinity:
16066 llvm_unreachable(
"Unexpected OpenMP clause.");
16068 return CaptureRegion;
16078 Stmt *HelperValStmt =
nullptr;
16081 !
Condition->isInstantiationDependent() &&
16082 !
Condition->containsUnexpandedParameterPack()) {
16087 ValExpr = Val.
get();
16091 DKind, OMPC_if,
LangOpts.OpenMP, NameModifier);
16094 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16095 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
16101 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
16102 LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
16110 Stmt *HelperValStmt =
nullptr;
16113 !
Condition->isInstantiationDependent() &&
16114 !
Condition->containsUnexpandedParameterPack()) {
16126 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16127 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
16133 StartLoc, LParenLoc, EndLoc);
16143 IntConvertDiagnoser()
16147 return S.
Diag(Loc, diag::err_omp_not_integral) << T;
16151 return S.
Diag(Loc, diag::err_omp_incomplete_type) << T;
16156 return S.
Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
16165 return S.
Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
16174 llvm_unreachable(
"conversion functions are permitted");
16176 } ConvertDiagnoser;
16182 bool StrictlyPositive,
bool BuildCapture =
false,
16185 Stmt **HelperValStmt =
nullptr) {
16191 if (
Value.isInvalid())
16194 ValExpr =
Value.get();
16198 if (
Result->isSigned() &&
16199 !((!StrictlyPositive &&
Result->isNonNegative()) ||
16200 (StrictlyPositive &&
Result->isStrictlyPositive()))) {
16201 SemaRef.
Diag(Loc, diag::err_omp_negative_expression_in_clause)
16202 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
16211 if (*CaptureRegion != OMPD_unknown &&
16214 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16215 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
16226 Expr *ValExpr = NumThreads;
16227 Stmt *HelperValStmt =
nullptr;
16240 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16241 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
16246 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
16251 bool StrictlyPositive,
16252 bool SuppressExprDiags) {
16261 if (SuppressExprDiags) {
16265 SuppressedDiagnoser() : VerifyICEDiagnoser(
true) {}
16268 llvm_unreachable(
"Diagnostic suppressed");
16278 if ((StrictlyPositive && !
Result.isStrictlyPositive()) ||
16279 (!StrictlyPositive && !
Result.isNonNegative())) {
16280 Diag(E->
getExprLoc(), diag::err_omp_negative_expression_in_clause)
16281 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
16285 if ((CKind == OMPC_aligned || CKind == OMPC_align) && !
Result.isPowerOf2()) {
16286 Diag(E->
getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
16290 if (CKind == OMPC_collapse &&
DSAStack->getAssociatedLoops() == 1)
16292 else if (CKind == OMPC_ordered)
16303 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
16316 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
16325 DSAStackTy *Stack) {
16326 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT();
16327 if (!OMPAllocatorHandleT.
isNull())
16330 bool ErrorFound =
false;
16331 for (
int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
16332 auto AllocatorKind =
static_cast<OMPAllocateDeclAttr::AllocatorTypeTy
>(I);
16333 StringRef Allocator =
16334 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
16336 auto *VD = dyn_cast_or_null<ValueDecl>(
16349 if (OMPAllocatorHandleT.
isNull())
16350 OMPAllocatorHandleT = AllocatorType;
16355 Stack->setAllocator(AllocatorKind, Res.
get());
16358 S.
Diag(Loc, diag::err_omp_implied_type_not_found)
16359 <<
"omp_allocator_handle_t";
16363 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT);
16376 if (Allocator.isInvalid())
16379 DSAStack->getOMPAllocatorHandleT(),
16382 if (Allocator.isInvalid())
16398 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
16408 Expr *NumForLoops) {
16414 if (NumForLoops && LParenLoc.
isValid()) {
16416 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
16419 NumForLoops = NumForLoopsResult.
get();
16421 NumForLoops =
nullptr;
16424 Context, NumForLoops, NumForLoops ?
DSAStack->getAssociatedLoops() : 0,
16425 StartLoc, LParenLoc, EndLoc);
16426 DSAStack->setOrderedRegion(
true, NumForLoops, Clause);
16437 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16439 case OMPC_proc_bind:
16441 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16443 case OMPC_atomic_default_mem_order:
16446 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16450 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16454 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16458 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16462 case OMPC_num_threads:
16466 case OMPC_allocator:
16467 case OMPC_collapse:
16468 case OMPC_schedule:
16470 case OMPC_firstprivate:
16471 case OMPC_lastprivate:
16473 case OMPC_reduction:
16474 case OMPC_task_reduction:
16475 case OMPC_in_reduction:
16479 case OMPC_copyprivate:
16483 case OMPC_mergeable:
16484 case OMPC_threadprivate:
16485 case OMPC_allocate:
16502 case OMPC_num_teams:
16503 case OMPC_thread_limit:
16504 case OMPC_priority:
16505 case OMPC_grainsize:
16507 case OMPC_num_tasks:
16509 case OMPC_dist_schedule:
16510 case OMPC_defaultmap:
16515 case OMPC_use_device_ptr:
16516 case OMPC_use_device_addr:
16517 case OMPC_is_device_ptr:
16518 case OMPC_has_device_addr:
16519 case OMPC_unified_address:
16520 case OMPC_unified_shared_memory:
16521 case OMPC_reverse_offload:
16522 case OMPC_dynamic_allocators:
16523 case OMPC_device_type:
16525 case OMPC_nontemporal:
16527 case OMPC_novariants:
16528 case OMPC_nocontext:
16530 case OMPC_inclusive:
16531 case OMPC_exclusive:
16532 case OMPC_uses_allocators:
16533 case OMPC_affinity:
16536 llvm_unreachable(
"Clause is not allowed.");
16545 llvm::raw_svector_ostream Out(Buffer);
16546 unsigned Skipped = Exclude.size();
16547 auto S = Exclude.begin(), E = Exclude.end();
16548 for (
unsigned I =
First; I <
Last; ++I) {
16549 if (std::find(S, E, I) != E) {
16554 if (I + Skipped + 2 ==
Last)
16556 else if (I + Skipped + 1 !=
Last)
16559 return std::string(Out.str());
16567 if (Kind == OMP_DEFAULT_unknown) {
16568 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16570 unsigned(OMP_DEFAULT_unknown))
16571 << getOpenMPClauseName(OMPC_default);
16576 case OMP_DEFAULT_none:
16577 DSAStack->setDefaultDSANone(KindKwLoc);
16579 case OMP_DEFAULT_shared:
16580 DSAStack->setDefaultDSAShared(KindKwLoc);
16582 case OMP_DEFAULT_firstprivate:
16583 DSAStack->setDefaultDSAFirstPrivate(KindKwLoc);
16585 case OMP_DEFAULT_private:
16586 DSAStack->setDefaultDSAPrivate(KindKwLoc);
16589 llvm_unreachable(
"DSA unexpected in OpenMP default clause");
16601 if (Kind == OMP_PROC_BIND_unknown) {
16602 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16604 unsigned(OMP_PROC_BIND_master),
16607 ? OMP_PROC_BIND_primary
16608 : OMP_PROC_BIND_spread) +
16610 << getOpenMPClauseName(OMPC_proc_bind);
16613 if (Kind == OMP_PROC_BIND_primary &&
LangOpts.OpenMP < 51)
16614 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16616 unsigned(OMP_PROC_BIND_master),
16618 unsigned(OMP_PROC_BIND_spread) + 1)
16619 << getOpenMPClauseName(OMPC_proc_bind);
16628 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16630 OMPC_atomic_default_mem_order, 0,
16632 << getOpenMPClauseName(OMPC_atomic_default_mem_order);
16636 LParenLoc, EndLoc);
16646 "OMPC_ORDER_unknown not greater than 0");
16647 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16650 << getOpenMPClauseName(OMPC_order);
16663 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) {
16665 OMPC_DEPEND_source, OMPC_DEPEND_sink, OMPC_DEPEND_depobj,
16666 OMPC_DEPEND_outallmemory, OMPC_DEPEND_inoutallmemory};
16668 Except.push_back(OMPC_DEPEND_inoutset);
16669 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16672 << getOpenMPClauseName(OMPC_update);
16683 for (
Expr *SizeExpr : SizeExprs) {
16684 ExprResult NumForLoopsResult = VerifyPositiveIntegerConstantInClause(
16685 SizeExpr, OMPC_sizes,
true);
16686 if (!NumForLoopsResult.
isUsable())
16690 DSAStack->setAssociatedLoops(SizeExprs.size());
16707 ExprResult FactorResult = VerifyPositiveIntegerConstantInClause(
16708 FactorExpr, OMPC_partial,
true);
16711 FactorExpr = FactorResult.
get();
16722 AlignVal = VerifyPositiveIntegerConstantInClause(A, OMPC_align);
16736 case OMPC_schedule:
16737 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
16738 assert(Argument.size() == NumberOfElements &&
16739 ArgumentLoc.size() == NumberOfElements);
16744 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
16745 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
16748 assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
16750 Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
16753 case OMPC_dist_schedule:
16756 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
16758 case OMPC_defaultmap:
16759 enum { Modifier, DefaultmapKind };
16763 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
16767 assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
16770 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
16773 case OMPC_num_threads:
16777 case OMPC_allocator:
16778 case OMPC_collapse:
16780 case OMPC_proc_bind:
16782 case OMPC_firstprivate:
16783 case OMPC_lastprivate:
16785 case OMPC_reduction:
16786 case OMPC_task_reduction:
16787 case OMPC_in_reduction:
16791 case OMPC_copyprivate:
16795 case OMPC_mergeable:
16796 case OMPC_threadprivate:
16797 case OMPC_allocate:
16814 case OMPC_num_teams:
16815 case OMPC_thread_limit:
16816 case OMPC_priority:
16817 case OMPC_grainsize:
16819 case OMPC_num_tasks:
16825 case OMPC_use_device_ptr:
16826 case OMPC_use_device_addr:
16827 case OMPC_is_device_ptr:
16828 case OMPC_has_device_addr:
16829 case OMPC_unified_address:
16830 case OMPC_unified_shared_memory:
16831 case OMPC_reverse_offload:
16832 case OMPC_dynamic_allocators:
16833 case OMPC_atomic_default_mem_order:
16834 case OMPC_device_type:
16836 case OMPC_nontemporal:
16839 case OMPC_novariants:
16840 case OMPC_nocontext:
16842 case OMPC_inclusive:
16843 case OMPC_exclusive:
16844 case OMPC_uses_allocators:
16845 case OMPC_affinity:
16849 llvm_unreachable(
"Clause is not allowed.");
16860 Excluded.push_back(M2);
16861 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
16862 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
16863 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
16864 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
16865 S.
Diag(M1Loc, diag::err_omp_unexpected_clause_value)
16870 << getOpenMPClauseName(OMPC_schedule);
16888 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
16889 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
16890 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
16891 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
16892 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
16898 std::string Values;
16908 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
16909 << Values << getOpenMPClauseName(OMPC_schedule);
16917 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
16918 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
16919 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
16920 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
16921 diag::err_omp_schedule_nonmonotonic_static);
16924 Expr *ValExpr = ChunkSize;
16925 Stmt *HelperValStmt =
nullptr;
16936 ValExpr = Val.
get();
16943 if (
Result->isSigned() && !
Result->isStrictlyPositive()) {
16944 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
16949 DSAStack->getCurrentDirective(), OMPC_schedule,
16950 LangOpts.OpenMP) != OMPD_unknown &&
16953 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16954 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
16962 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
16979 case OMPC_mergeable:
17021 case OMPC_unified_address:
17024 case OMPC_unified_shared_memory:
17027 case OMPC_reverse_offload:
17030 case OMPC_dynamic_allocators:
17046 case OMPC_num_threads:
17050 case OMPC_allocator:
17051 case OMPC_collapse:
17052 case OMPC_schedule:
17054 case OMPC_firstprivate:
17055 case OMPC_lastprivate:
17057 case OMPC_reduction:
17058 case OMPC_task_reduction:
17059 case OMPC_in_reduction:
17063 case OMPC_copyprivate:
17065 case OMPC_proc_bind:
17066 case OMPC_threadprivate:
17067 case OMPC_allocate:
17073 case OMPC_num_teams:
17074 case OMPC_thread_limit:
17075 case OMPC_priority:
17076 case OMPC_grainsize:
17077 case OMPC_num_tasks:
17079 case OMPC_dist_schedule:
17080 case OMPC_defaultmap:
17085 case OMPC_use_device_ptr:
17086 case OMPC_use_device_addr:
17087 case OMPC_is_device_ptr:
17088 case OMPC_has_device_addr:
17089 case OMPC_atomic_default_mem_order:
17090 case OMPC_device_type:
17092 case OMPC_nontemporal:
17094 case OMPC_novariants:
17095 case OMPC_nocontext:
17097 case OMPC_inclusive:
17098 case OMPC_exclusive:
17099 case OMPC_uses_allocators:
17100 case OMPC_affinity:
17103 llvm_unreachable(
"Clause is not allowed.");
17216 if (!
hasClauses(Clauses, OMPC_init, OMPC_use, OMPC_destroy, OMPC_nowait)) {
17217 StringRef
Expected =
"'init', 'use', 'destroy', or 'nowait'";
17218 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
17219 <<
Expected << getOpenMPDirectiveName(OMPD_interop);
17232 bool HasInitClause =
false;
17233 bool IsTargetSync =
false;
17237 if (
const auto *InitClause = dyn_cast<OMPInitClause>(
C)) {
17238 HasInitClause =
true;
17239 if (InitClause->getIsTargetSync())
17240 IsTargetSync =
true;
17241 }
else if (
const auto *DC = dyn_cast<OMPDependClause>(
C)) {
17245 if (DependClause && HasInitClause && !IsTargetSync) {
17246 Diag(DependClause->
getBeginLoc(), diag::err_omp_interop_bad_depend_clause);
17259 if (ClauseKind == OMPC_init) {
17261 VarLoc = IC->getVarLoc();
17262 DRE = dyn_cast_or_null<DeclRefExpr>(IC->getInteropVar());
17263 }
else if (ClauseKind == OMPC_use) {
17265 VarLoc = UC->getVarLoc();
17266 DRE = dyn_cast_or_null<DeclRefExpr>(UC->getInteropVar());
17267 }
else if (ClauseKind == OMPC_destroy) {
17269 VarLoc = DC->getVarLoc();
17270 DRE = dyn_cast_or_null<DeclRefExpr>(DC->getInteropVar());
17276 if (
const auto *VD = dyn_cast<VarDecl>(DRE->
getDecl())) {
17278 Diag(VarLoc, diag::err_omp_interop_var_multiple_actions) << VD;
17295 const auto *DRE = dyn_cast<DeclRefExpr>(InteropVarExpr);
17296 if (!DRE || !isa<VarDecl>(DRE->getDecl())) {
17297 SemaRef.
Diag(VarLoc, diag::err_omp_interop_variable_expected) << 0;
17302 bool HasError =
false;
17308 if (
const auto *TD = dyn_cast<TypeDecl>(ND)) {
17309 InteropType =
QualType(TD->getTypeForDecl(), 0);
17318 SemaRef.
Diag(VarLoc, diag::err_omp_implied_type_not_found)
17319 <<
"omp_interop_t";
17325 SemaRef.
Diag(VarLoc, diag::err_omp_interop_variable_wrong_type);
17331 if ((Kind == OMPC_init || Kind == OMPC_destroy) &&
17333 SemaRef.
Diag(VarLoc, diag::err_omp_interop_variable_expected)
17342 bool IsTarget,
bool IsTargetSync,
17351 for (
const Expr *E : PrefExprs) {
17357 if (isa<StringLiteral>(E))
17364 IsTargetSync, StartLoc, LParenLoc, VarLoc,
17377 OMPUseClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
17398 Stmt *HelperValStmt =
nullptr;
17401 !
Condition->isInstantiationDependent() &&
17402 !
Condition->containsUnexpandedParameterPack()) {
17414 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
17415 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
17421 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
17429 Stmt *HelperValStmt =
nullptr;
17432 !
Condition->isInstantiationDependent() &&
17433 !
Condition->containsUnexpandedParameterPack()) {
17445 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
17446 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
17452 StartLoc, LParenLoc, EndLoc);
17459 Expr *ValExpr = ThreadID;
17460 Stmt *HelperValStmt =
nullptr;
17467 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
17468 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
17473 StartLoc, LParenLoc, EndLoc);
17491 case OMPC_firstprivate:
17494 case OMPC_lastprivate:
17496 "Unexpected lastprivate modifier.");
17499 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
17504 case OMPC_reduction:
17506 "Unexpected lastprivate modifier.");
17509 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc,
17512 case OMPC_task_reduction:
17514 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc,
17517 case OMPC_in_reduction:
17519 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc,
17524 "Unexpected linear modifier.");
17532 LParenLoc, ColonLoc, EndLoc);
17537 case OMPC_copyprivate:
17545 "Unexpected depend modifier.");
17553 "Unexpected map modifier.");
17558 ExtraModifierLoc, ColonLoc, VarList, Locs);
17572 case OMPC_use_device_ptr:
17575 case OMPC_use_device_addr:
17578 case OMPC_is_device_ptr:
17581 case OMPC_has_device_addr:
17584 case OMPC_allocate:
17586 LParenLoc, ColonLoc, EndLoc);
17588 case OMPC_nontemporal:
17591 case OMPC_inclusive:
17594 case OMPC_exclusive:
17597 case OMPC_affinity:
17604 case OMPC_num_threads:
17608 case OMPC_allocator:
17609 case OMPC_collapse:
17611 case OMPC_proc_bind:
17612 case OMPC_schedule:
17616 case OMPC_mergeable:
17617 case OMPC_threadprivate:
17631 case OMPC_num_teams:
17632 case OMPC_thread_limit:
17633 case OMPC_priority:
17634 case OMPC_grainsize:
17636 case OMPC_num_tasks:
17638 case OMPC_dist_schedule:
17639 case OMPC_defaultmap:
17642 case OMPC_unified_address:
17643 case OMPC_unified_shared_memory:
17644 case OMPC_reverse_offload:
17645 case OMPC_dynamic_allocators:
17646 case OMPC_atomic_default_mem_order:
17647 case OMPC_device_type:
17651 case OMPC_novariants:
17652 case OMPC_nocontext:
17654 case OMPC_uses_allocators:
17658 llvm_unreachable(
"Clause is not allowed.");
17688 bool IsImplicitClause =
17690 for (
Expr *RefExpr : VarList) {
17691 assert(RefExpr &&
"NULL expr in OpenMP private clause.");
17694 Expr *SimpleRefExpr = RefExpr;
17698 Vars.push_back(RefExpr);
17699 PrivateCopies.push_back(
nullptr);
17706 auto *VD = dyn_cast<VarDecl>(D);
17713 Type =
Type.getNonReferenceType();
17733 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
17734 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
17735 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
17736 << getOpenMPClauseName(OMPC_private);
17745 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
17746 << getOpenMPClauseName(OMPC_private) <<
Type
17747 << getOpenMPDirectiveName(CurrDir);
17748 bool IsDecl = !VD || VD->isThisDeclarationADefinition(
Context) ==
17751 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17765 CurrDir == OMPD_target) {
17767 if (
DSAStack->checkMappableExprComponentListsForDecl(
17771 ConflictKind = WhereFoundClauseKind;
17774 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
17775 << getOpenMPClauseName(OMPC_private)
17776 << getOpenMPClauseName(ConflictKind)
17777 << getOpenMPDirectiveName(CurrDir);
17796 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
17805 auto *FD = dyn_cast<FieldDecl>(D);
17809 RefExpr->getExprLoc());
17813 if (!IsImplicitClause)
17814 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
17816 ? RefExpr->IgnoreParens()
17818 PrivateCopies.push_back(VDPrivateRefExpr);
17836 bool IsImplicitClause =
17840 for (
Expr *RefExpr : VarList) {
17841 assert(RefExpr &&
"NULL expr in OpenMP firstprivate clause.");
17844 Expr *SimpleRefExpr = RefExpr;
17848 Vars.push_back(RefExpr);
17849 PrivateCopies.push_back(
nullptr);
17850 Inits.push_back(
nullptr);
17856 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
17858 auto *VD = dyn_cast<VarDecl>(D);
17864 diag::err_omp_firstprivate_incomplete_type))
17866 Type =
Type.getNonReferenceType();
17875 DSAStackTy::DSAVarData TopDVar;
17876 if (!IsImplicitClause) {
17877 DSAStackTy::DSAVarData DVar =
17889 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
17891 DVar.CKind != OMPC_lastprivate) &&
17893 Diag(ELoc, diag::err_omp_wrong_dsa)
17894 << getOpenMPClauseName(DVar.CKind)
17895 << getOpenMPClauseName(OMPC_firstprivate);
17911 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
17912 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
17913 Diag(ELoc, diag::err_omp_wrong_dsa)
17914 << getOpenMPClauseName(DVar.CKind)
17915 << getOpenMPClauseName(OMPC_firstprivate);
17939 DVar =
DSAStack->getImplicitDSA(D,
true);
17940 if (DVar.CKind != OMPC_shared &&
17943 DVar.DKind == OMPD_unknown)) {
17944 Diag(ELoc, diag::err_omp_required_access)
17945 << getOpenMPClauseName(OMPC_firstprivate)
17946 << getOpenMPClauseName(OMPC_shared);
17966 return C == OMPC_reduction && !AppliedToPointee;
17974 if (DVar.CKind == OMPC_reduction &&
17978 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
17979 << getOpenMPDirectiveName(DVar.DKind);
17995 CurrDir == OMPD_target) {
17997 if (
DSAStack->checkMappableExprComponentListsForDecl(
18002 ConflictKind = WhereFoundClauseKind;
18005 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
18006 << getOpenMPClauseName(OMPC_firstprivate)
18007 << getOpenMPClauseName(ConflictKind)
18008 << getOpenMPDirectiveName(
DSAStack->getCurrentDirective());
18018 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
18019 << getOpenMPClauseName(OMPC_firstprivate) <<
Type
18020 << getOpenMPDirectiveName(
DSAStack->getCurrentDirective());
18021 bool IsDecl = !VD || VD->isThisDeclarationADefinition(
Context) ==
18024 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18033 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
18039 Expr *VDInitRefExpr =
nullptr;
18049 ".firstprivate.temp");
18064 ".firstprivate.temp");
18066 RefExpr->getExprLoc());
18072 if (IsImplicitClause) {
18073 Diag(RefExpr->getExprLoc(),
18074 diag::note_omp_task_predetermined_firstprivate_here);
18081 RefExpr->getExprLoc());
18084 if (TopDVar.CKind == OMPC_lastprivate) {
18085 Ref = TopDVar.PrivateCopy;
18087 auto *FD = dyn_cast<FieldDecl>(D);
18091 RefExpr->getExprLoc());
18095 ExprCaptures.push_back(Ref->
getDecl());
18098 if (!IsImplicitClause)
18099 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
18101 ? RefExpr->IgnoreParens()
18103 PrivateCopies.push_back(VDPrivateRefExpr);
18104 Inits.push_back(VDInitRefExpr);
18111 Vars, PrivateCopies, Inits,
18120 assert(ColonLoc.
isValid() &&
"Colon location must be valid.");
18121 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value)
18124 << getOpenMPClauseName(OMPC_lastprivate);
18134 for (
Expr *RefExpr : VarList) {
18135 assert(RefExpr &&
"NULL expr in OpenMP lastprivate clause.");
18138 Expr *SimpleRefExpr = RefExpr;
18142 Vars.push_back(RefExpr);
18143 SrcExprs.push_back(
nullptr);
18144 DstExprs.push_back(
nullptr);
18145 AssignmentOps.push_back(
nullptr);
18152 auto *VD = dyn_cast<VarDecl>(D);
18158 diag::err_omp_lastprivate_incomplete_type))
18160 Type =
Type.getNonReferenceType();
18177 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar);
18178 bool IsDecl = !VD || VD->isThisDeclarationADefinition(
Context) ==
18181 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18195 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
18196 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
18198 DVar.CKind != OMPC_firstprivate) &&
18199 (DVar.CKind != OMPC_private || DVar.RefExpr !=
nullptr)) {
18200 Diag(ELoc, diag::err_omp_wrong_dsa)
18201 << getOpenMPClauseName(DVar.CKind)
18202 << getOpenMPClauseName(OMPC_lastprivate);
18213 DSAStackTy::DSAVarData TopDVar = DVar;
18217 DVar =
DSAStack->getImplicitDSA(D,
true);
18218 if (DVar.CKind != OMPC_shared) {
18219 Diag(ELoc, diag::err_omp_required_access)
18220 << getOpenMPClauseName(OMPC_lastprivate)
18221 << getOpenMPClauseName(OMPC_shared);
18237 Type.getUnqualifiedType(),
".lastprivate.src",
18248 PseudoDstExpr, PseudoSrcExpr);
18258 if (TopDVar.CKind == OMPC_firstprivate) {
18259 Ref = TopDVar.PrivateCopy;
18263 ExprCaptures.push_back(Ref->
getDecl());
18265 if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) ||
18276 ExprPostUpdates.push_back(
18280 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
18282 ? RefExpr->IgnoreParens()
18284 SrcExprs.push_back(PseudoSrcExpr);
18285 DstExprs.push_back(PseudoDstExpr);
18286 AssignmentOps.push_back(AssignmentOp.
get());
18293 Vars, SrcExprs, DstExprs, AssignmentOps,
18294 LPKind, LPKindLoc, ColonLoc,
18304 for (
Expr *RefExpr : VarList) {
18305 assert(RefExpr &&
"NULL expr in OpenMP lastprivate clause.");
18308 Expr *SimpleRefExpr = RefExpr;
18312 Vars.push_back(RefExpr);
18318 auto *VD = dyn_cast<VarDecl>(D);
18326 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
18327 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
18329 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
18330 << getOpenMPClauseName(OMPC_shared);
18338 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
18340 ? RefExpr->IgnoreParens()
18351class DSARefChecker :
public StmtVisitor<DSARefChecker, bool> {
18356 if (
auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
18357 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD,
false);
18358 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
18360 if (DVar.CKind != OMPC_unknown)
18362 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
18369 return DVarPrivate.CKind != OMPC_unknown;
18373 bool VisitStmt(
Stmt *S) {
18374 for (
Stmt *Child : S->children()) {
18375 if (Child && Visit(Child))
18380 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
18387class TransformExprToCaptures :
public TreeTransform<TransformExprToCaptures> {
18394 : BaseTransform(SemaRef),
Field(
FieldDecl), CapturedExpr(nullptr) {}
18399 CapturedExpr =
buildCapture(SemaRef, Field, E,
false);
18400 return CapturedExpr;
18402 return BaseTransform::TransformMemberExpr(E);
18404 DeclRefExpr *getCapturedExpr() {
return CapturedExpr; }
18408template <
typename T,
typename U>
18411 for (
U &Set : Lookups) {
18412 for (
auto *D : Set) {
18413 if (T Res = Gen(cast<ValueDecl>(D)))
18423 for (
auto RD : D->
redecls()) {
18446 AssociatedClasses);
18459 for (
auto *NS : AssociatedNamespaces) {
18472 for (
auto *D : R) {
18473 auto *Underlying = D;
18474 if (
auto *USD = dyn_cast<UsingShadowDecl>(D))
18475 Underlying = USD->getTargetDecl();
18477 if (!isa<OMPDeclareReductionDecl>(Underlying) &&
18478 !isa<OMPDeclareMapperDecl>(Underlying))
18485 if (
auto *USD = dyn_cast<UsingShadowDecl>(D))
18486 Underlying = USD->getTargetDecl();
18488 Lookups.emplace_back();
18489 Lookups.back().addDecl(Underlying);
18508 S = S->getParent();
18509 }
while (S && !S->isDeclScope(D));
18511 S = S->getParent();
18512 Lookups.emplace_back();
18513 Lookups.back().append(Lookup.
begin(), Lookup.
end());
18516 }
else if (
auto *ULE =
18517 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
18519 Decl *PrevD =
nullptr;
18523 else if (
auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
18524 Lookups.back().addDecl(DRD);
18532 return !D->isInvalidDecl() &&
18533 (D->getType()->isDependentType() ||
18534 D->getType()->isInstantiationDependentType() ||
18535 D->getType()->containsUnexpandedParameterPack());
18541 ResSet.
append(Set.begin(), Set.end());
18543 ResSet.
addDecl(Set[Set.size() - 1]);
18548 true,
true, ResSet.
begin(), ResSet.
end());
18568 if (SemaRef.
isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
18569 TyRec->getDecl()->getDefinition()) {
18572 if (Lookup.
empty()) {
18573 Lookups.emplace_back();
18574 Lookups.back().append(Lookup.
begin(), Lookup.
end());
18605 Loc, VD->
getType(), Ty, Paths.front(),
18615 if (ReductionIdScopeSpec.
isSet()) {
18616 SemaRef.
Diag(Loc, diag::err_omp_not_resolved_reduction_identifier)
18625struct ReductionData {
18650 unsigned RedModifier = 0;
18651 ReductionData() =
delete;
18653 ReductionData(
unsigned Size,
unsigned Modifier = 0) : RedModifier(Modifier) {
18654 Vars.reserve(Size);
18655 Privates.reserve(Size);
18656 LHSs.reserve(Size);
18657 RHSs.reserve(Size);
18658 ReductionOps.reserve(Size);
18659 if (RedModifier == OMPC_REDUCTION_inscan) {
18660 InscanCopyOps.reserve(Size);
18661 InscanCopyArrayTemps.reserve(Size);
18662 InscanCopyArrayElems.reserve(Size);
18664 TaskgroupDescriptors.reserve(Size);
18665 ExprCaptures.reserve(Size);
18666 ExprPostUpdates.reserve(Size);
18670 void push(
Expr *Item,
Expr *ReductionOp) {
18671 Vars.emplace_back(Item);
18672 Privates.emplace_back(
nullptr);
18673 LHSs.emplace_back(
nullptr);
18674 RHSs.emplace_back(
nullptr);
18675 ReductionOps.emplace_back(ReductionOp);
18676 TaskgroupDescriptors.emplace_back(
nullptr);
18677 if (RedModifier == OMPC_REDUCTION_inscan) {
18678 InscanCopyOps.push_back(
nullptr);
18679 InscanCopyArrayTemps.push_back(
nullptr);
18680 InscanCopyArrayElems.push_back(
nullptr);
18685 Expr *TaskgroupDescriptor,
Expr *CopyOp,
Expr *CopyArrayTemp,
18686 Expr *CopyArrayElem) {
18687 Vars.emplace_back(Item);
18688 Privates.emplace_back(Private);
18689 LHSs.emplace_back(LHS);
18690 RHSs.emplace_back(RHS);
18691 ReductionOps.emplace_back(ReductionOp);
18692 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
18693 if (RedModifier == OMPC_REDUCTION_inscan) {
18694 InscanCopyOps.push_back(CopyOp);
18695 InscanCopyArrayTemps.push_back(CopyArrayTemp);
18696 InscanCopyArrayElems.push_back(CopyArrayElem);
18698 assert(CopyOp ==
nullptr && CopyArrayTemp ==
nullptr &&
18699 CopyArrayElem ==
nullptr &&
18700 "Copy operation must be used for inscan reductions only.");
18710 if (Length ==
nullptr) {
18717 SingleElement =
true;
18718 ArraySizes.push_back(llvm::APSInt::get(1));
18725 SingleElement = (ConstantLengthValue.getSExtValue() == 1);
18726 ArraySizes.push_back(ConstantLengthValue);
18734 while (
const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(
Base)) {
18735 Length = TempOASE->getLength();
18736 if (Length ==
nullptr) {
18743 ArraySizes.push_back(llvm::APSInt::get(1));
18750 if (ConstantLengthValue.getSExtValue() != 1)
18753 ArraySizes.push_back(ConstantLengthValue);
18755 Base = TempOASE->getBase()->IgnoreParenImpCasts();
18759 if (!SingleElement) {
18760 while (
const auto *TempASE = dyn_cast<ArraySubscriptExpr>(
Base)) {
18762 ArraySizes.push_back(llvm::APSInt::get(1));
18763 Base = TempASE->getBase()->IgnoreParenImpCasts();
18775 return BO_AddAssign;
18777 return BO_MulAssign;
18779 return BO_AndAssign;
18781 return BO_OrAssign;
18783 return BO_XorAssign;
18831 case OO_Array_Delete:
18840 case OO_GreaterEqual:
18842 case OO_MinusEqual:
18844 case OO_SlashEqual:
18845 case OO_PercentEqual:
18846 case OO_CaretEqual:
18850 case OO_GreaterGreater:
18851 case OO_LessLessEqual:
18852 case OO_GreaterGreaterEqual:
18853 case OO_EqualEqual:
18854 case OO_ExclaimEqual:
18857 case OO_MinusMinus:
18863 case OO_Conditional:
18866 llvm_unreachable(
"Unexpected reduction identifier");
18869 if (II->isStr(
"max"))
18871 else if (II->isStr(
"min"))
18877 if (ReductionIdScopeSpec.
isValid())
18883 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
18884 bool FirstIter =
true;
18885 for (
Expr *RefExpr : VarList) {
18886 assert(RefExpr &&
"nullptr expr in OpenMP reduction clause.");
18894 if (!FirstIter && IR != ER)
18899 Expr *SimpleRefExpr = RefExpr;
18908 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
18909 ReductionId,
Type, BasePath, IR == ER ?
nullptr : *IR);
18910 Expr *ReductionOp =
nullptr;
18912 (DeclareReductionRef.
isUnset() ||
18913 isa<UnresolvedLookupExpr>(DeclareReductionRef.
get())))
18914 ReductionOp = DeclareReductionRef.
get();
18916 RD.push(RefExpr, ReductionOp);
18922 Expr *TaskgroupDescriptor =
nullptr;
18924 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
18925 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
18927 Type = ASE->getType().getNonReferenceType();
18931 if (
const auto *ATy = BaseType->getAsArrayTypeUnsafe())
18932 Type = ATy->getElementType();
18935 Type =
Type.getNonReferenceType();
18939 auto *VD = dyn_cast<VarDecl>(D);
18945 diag::err_omp_reduction_incomplete_type))
18951 false, ASE || OASE))
18958 if (!ASE && !OASE) {
18960 VarDecl *VDDef = VD->getDefinition();
18962 DSARefChecker Check(Stack);
18963 if (Check.Visit(VDDef->
getInit())) {
18964 S.
Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
18965 << getOpenMPClauseName(ClauseKind) << ERange;
18983 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D,
false);
18984 if (DVar.CKind == OMPC_reduction) {
18985 S.
Diag(ELoc, diag::err_omp_once_referenced)
18986 << getOpenMPClauseName(ClauseKind);
18991 if (DVar.CKind != OMPC_unknown) {
18992 S.
Diag(ELoc, diag::err_omp_wrong_dsa)
18993 << getOpenMPClauseName(DVar.CKind)
18994 << getOpenMPClauseName(OMPC_reduction);
19006 DVar = Stack->getImplicitDSA(D,
true);
19007 if (DVar.CKind != OMPC_shared) {
19008 S.
Diag(ELoc, diag::err_omp_required_access)
19009 << getOpenMPClauseName(OMPC_reduction)
19010 << getOpenMPClauseName(OMPC_shared);
19018 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D,
false);
19019 if (DVar.CKind == OMPC_threadprivate) {
19020 S.
Diag(ELoc, diag::err_omp_wrong_dsa)
19021 << getOpenMPClauseName(DVar.CKind)
19022 << getOpenMPClauseName(OMPC_reduction);
19032 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
19033 ReductionId,
Type, BasePath, IR == ER ?
nullptr : *IR);
19037 (DeclareReductionRef.
isUnset() ||
19038 isa<UnresolvedLookupExpr>(DeclareReductionRef.
get()))) {
19039 RD.push(RefExpr, DeclareReductionRef.
get());
19042 if (BOK == BO_Comma && DeclareReductionRef.
isUnset()) {
19045 diag::err_omp_unknown_reduction_identifier)
19046 <<
Type << ReductionIdRange;
19058 if (DeclareReductionRef.
isUnset()) {
19059 if ((BOK == BO_GT || BOK == BO_LT) &&
19062 S.
Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
19063 << getOpenMPClauseName(ClauseKind) << S.
getLangOpts().CPlusPlus;
19064 if (!ASE && !OASE) {
19065 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19068 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19073 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
19075 S.
Diag(ELoc, diag::err_omp_clause_floating_type_arg)
19076 << getOpenMPClauseName(ClauseKind);
19077 if (!ASE && !OASE) {
19078 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19081 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19088 Type =
Type.getNonLValueExprType(Context).getUnqualifiedType();
19097 bool ConstantLengthOASE =
false;
19099 bool SingleElement;
19102 Context, OASE, SingleElement, ArraySizes);
19105 if (ConstantLengthOASE && !SingleElement) {
19106 for (llvm::APSInt &Size : ArraySizes)
19113 if ((OASE && !ConstantLengthOASE) ||
19118 S.
Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
19119 S.
Diag(ELoc, diag::note_vla_unsupported);
19122 S.
targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
19123 S.
targetDiag(ELoc, diag::note_vla_unsupported);
19136 }
else if (!ASE && !OASE &&
19144 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
19146 Expr *Init =
nullptr;
19149 if (DeclareReductionRef.
isUsable()) {
19152 if (DRD->getInitializer()) {
19178 Type = ComplexTy->getElementType();
19180 llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue(
19187 llvm::APInt InitValue = llvm::APInt::getAllOnes(Size);
19209 llvm::APInt InitValue =
19210 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
19211 : llvm::APInt::getMinValue(Size)
19212 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
19213 : llvm::APInt::getMaxValue(Size);
19224 llvm::APFloat InitValue = llvm::APFloat::getLargest(
19255 llvm_unreachable(
"Unexpected reduction operation");
19258 if (Init && DeclareReductionRef.
isUnset()) {
19264 }
else if (!Init) {
19274 S.
Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
19275 <<
Type << ReductionIdRange;
19276 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19279 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19285 if (DeclareReductionRef.
isUsable()) {
19290 if (!BasePath.empty()) {
19294 Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.
get(), &BasePath,
19297 Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.
get(), &BasePath,
19301 QualType Params[] = {PtrRedTy, PtrRedTy};
19316 CombBOK, LHSDRE, RHSDRE);
19323 if (BOK != BO_LT && BOK != BO_GT) {
19326 BO_Assign, LHSDRE, ReductionOp.
get());
19328 auto *ConditionalOp =
new (Context)
19333 BO_Assign, LHSDRE, ConditionalOp);
19346 ExprResult CopyOpRes, TempArrayRes, TempArrayElem;
19347 if (ClauseKind == OMPC_reduction &&
19348 RD.RedModifier == OMPC_REDUCTION_inscan) {
19350 CopyOpRes = S.
BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE,
19360 if (Stack->getCurrentDirective() == OMPD_simd ||
19398 if (ClauseKind == OMPC_in_reduction) {
19401 const Expr *ParentReductionOp =
nullptr;
19402 Expr *ParentBOKTD =
nullptr, *ParentReductionOpTD =
nullptr;
19403 DSAStackTy::DSAVarData ParentBOKDSA =
19404 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
19406 DSAStackTy::DSAVarData ParentReductionOpDSA =
19407 Stack->getTopMostTaskgroupReductionData(
19408 D, ParentSR, ParentReductionOp, ParentReductionOpTD);
19409 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
19410 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
19411 if ((DeclareReductionRef.
isUnset() && IsParentReductionOp) ||
19412 (DeclareReductionRef.
isUsable() && IsParentBOK) ||
19413 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) {
19414 bool EmitError =
true;
19415 if (IsParentReductionOp && DeclareReductionRef.
isUsable()) {
19416 llvm::FoldingSetNodeID RedId, ParentRedId;
19417 ParentReductionOp->
Profile(ParentRedId, Context,
true);
19418 DeclareReductionRef.
get()->
Profile(RedId, Context,
19420 EmitError = RedId != ParentRedId;
19424 diag::err_omp_reduction_identifier_mismatch)
19425 << ReductionIdRange << RefExpr->getSourceRange();
19427 diag::note_omp_previous_reduction_identifier)
19429 << (IsParentBOK ? ParentBOKDSA.RefExpr
19430 : ParentReductionOpDSA.RefExpr)
19431 ->getSourceRange();
19435 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
19442 TransformExprToCaptures RebuildToCapture(S, D);
19444 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
19445 Ref = RebuildToCapture.getCapturedExpr();
19447 VarsExpr = Ref =
buildCapture(S, D, SimpleRefExpr,
false);
19450 RD.ExprCaptures.emplace_back(Ref->
getDecl());
19456 S.
BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
19461 Stack->getCurrentDirective() == OMPD_taskgroup) {
19462 S.
Diag(RefExpr->getExprLoc(),
19463 diag::err_omp_reduction_non_addressable_expression)
19464 << RefExpr->getSourceRange();
19467 RD.ExprPostUpdates.emplace_back(
19474 unsigned Modifier = RD.RedModifier;
19477 if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction)
19478 Modifier = OMPC_REDUCTION_task;
19479 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier,
19481 if (Modifier == OMPC_REDUCTION_task &&
19482 (CurrDir == OMPD_taskgroup ||
19486 if (DeclareReductionRef.
isUsable())
19487 Stack->addTaskgroupReductionData(D, ReductionIdRange,
19488 DeclareReductionRef.
get());
19490 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
19492 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.
get(),
19493 TaskgroupDescriptor, CopyOpRes.
get(), TempArrayRes.
get(),
19494 TempArrayElem.
get());
19496 return RD.Vars.empty();
19506 Diag(LParenLoc, diag::err_omp_unexpected_clause_value)
19509 << getOpenMPClauseName(OMPC_reduction);
19517 if (Modifier == OMPC_REDUCTION_inscan &&
19518 (
DSAStack->getCurrentDirective() != OMPD_for &&
19519 DSAStack->getCurrentDirective() != OMPD_for_simd &&
19520 DSAStack->getCurrentDirective() != OMPD_simd &&
19521 DSAStack->getCurrentDirective() != OMPD_parallel_for &&
19522 DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) {
19523 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction);
19527 ReductionData RD(VarList.size(), Modifier);
19529 StartLoc, LParenLoc, ColonLoc, EndLoc,
19530 ReductionIdScopeSpec, ReductionId,
19531 UnresolvedReductions, RD))
19535 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier,
19537 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps,
19538 RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems,
19548 ReductionData RD(VarList.size());
19550 StartLoc, LParenLoc, ColonLoc, EndLoc,
19551 ReductionIdScopeSpec, ReductionId,
19552 UnresolvedReductions, RD))
19556 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
19558 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
19568 ReductionData RD(VarList.size());
19570 StartLoc, LParenLoc, ColonLoc, EndLoc,
19571 ReductionIdScopeSpec, ReductionId,
19572 UnresolvedReductions, RD))
19576 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
19578 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
19585 if ((!
LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
19587 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) <<
LangOpts.CPlusPlus;
19595 bool IsDeclareSimd) {
19596 const auto *VD = dyn_cast_or_null<VarDecl>(D);
19600 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
19602 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
19606 Type =
Type.getNonReferenceType();
19613 if (!IsDeclareSimd &&
19618 Type =
Type.getUnqualifiedType().getCanonicalType();
19619 const auto *Ty =
Type.getTypePtrOrNull();
19620 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() &&
19621 !Ty->isIntegralType(
Context) && !Ty->isPointerType())) {
19622 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) <<
Type;
19624 bool IsDecl = !VD || VD->isThisDeclarationADefinition(
Context) ==
19627 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19645 LinKind = OMPC_LINEAR_val;
19646 for (
Expr *RefExpr : VarList) {
19647 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
19650 Expr *SimpleRefExpr = RefExpr;
19654 Vars.push_back(RefExpr);
19655 Privates.push_back(
nullptr);
19656 Inits.push_back(
nullptr);
19663 auto *VD = dyn_cast<VarDecl>(D);
19669 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
19670 if (DVar.RefExpr) {
19671 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
19672 << getOpenMPClauseName(OMPC_linear);
19679 Type =
Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
19685 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
19694 ExprCaptures.push_back(Ref->
getDecl());
19701 SimpleRefExpr, RefRes.
get());
19704 ExprPostUpdates.push_back(
19709 if (LinKind == OMPC_LINEAR_uval)
19710 InitExpr = VD ? VD->getInit() : SimpleRefExpr;
19712 InitExpr = VD ? SimpleRefExpr : Ref;
19717 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
19719 ? RefExpr->IgnoreParens()
19721 Privates.push_back(PrivateRef);
19722 Inits.push_back(InitRef);
19728 Expr *StepExpr = Step;
19729 Expr *CalcStepExpr =
nullptr;
19737 StepExpr = Val.
get();
19745 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.
get(), StepExpr);
19752 if (!
Result->isNegative() && !
Result->isStrictlyPositive())
19753 Diag(StepLoc, diag::warn_omp_linear_step_zero)
19754 << Vars[0] << (Vars.size() > 1);
19758 CalcStepExpr = CalcStep.
get();
19763 ColonLoc, EndLoc, Vars, Privates, Inits,
19764 StepExpr, CalcStepExpr,
19770 Expr *NumIterations,
Sema &SemaRef,
19771 Scope *S, DSAStackTy *Stack) {
19776 Expr *Step = Clause.getStep();
19777 Expr *CalcStep = Clause.getCalcStep();
19784 bool HasErrors =
false;
19785 auto CurInit = Clause.inits().begin();
19786 auto CurPrivate = Clause.privates().begin();
19788 for (
Expr *RefExpr : Clause.varlists()) {
19791 Expr *SimpleRefExpr = RefExpr;
19792 auto Res =
getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
19794 if (Res.second || !D) {
19795 Updates.push_back(
nullptr);
19796 Finals.push_back(
nullptr);
19800 auto &&Info = Stack->isLoopControlVariable(D);
19807 diag::err_omp_linear_distribute_var_non_loop_iteration);
19808 Updates.push_back(
nullptr);
19809 Finals.push_back(
nullptr);
19813 Expr *InitExpr = *CurInit;
19818 if (LinKind == OMPC_LINEAR_uval)
19823 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
19830 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
19833 Update = *CurPrivate;
19841 S, RefExpr->getExprLoc(), BO_Assign, CapturedRef,
19844 Final = *CurPrivate;
19848 if (!Update.isUsable() || !Final.isUsable()) {
19849 Updates.push_back(
nullptr);
19850 Finals.push_back(
nullptr);
19851 UsedExprs.push_back(
nullptr);
19854 Updates.push_back(Update.get());
19855 Finals.push_back(Final.get());
19857 UsedExprs.push_back(SimpleRefExpr);
19862 if (
Expr *S = Clause.getStep())
19863 UsedExprs.push_back(S);
19865 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(),
nullptr);
19866 Clause.setUpdates(Updates);
19867 Clause.setFinals(Finals);
19868 Clause.setUsedExprs(UsedExprs);
19876 for (
Expr *RefExpr : VarList) {
19877 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
19880 Expr *SimpleRefExpr = RefExpr;
19884 Vars.push_back(RefExpr);
19891 auto *VD = dyn_cast<VarDecl>(D);
19899 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
19901 bool IsDecl = !VD || VD->isThisDeclarationADefinition(
Context) ==
19904 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19911 if (
const Expr *PrevRef =
DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
19912 Diag(ELoc, diag::err_omp_used_in_clause_twice)
19913 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange;
19914 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
19915 << getOpenMPClauseName(OMPC_aligned);
19923 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
19932 if (Alignment !=
nullptr) {
19934 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
19937 Alignment = AlignResult.
get();
19943 EndLoc, Vars, Alignment);
19954 for (
Expr *RefExpr : VarList) {
19955 assert(RefExpr &&
"NULL expr in OpenMP copyin clause.");
19956 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
19958 Vars.push_back(RefExpr);
19959 SrcExprs.push_back(
nullptr);
19960 DstExprs.push_back(
nullptr);
19961 AssignmentOps.push_back(
nullptr);
19970 auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
19971 if (!DE || !isa<VarDecl>(DE->getDecl())) {
19972 Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
19973 << 0 << RefExpr->getSourceRange();
19977 Decl *D = DE->getDecl();
19983 Vars.push_back(DE);
19984 SrcExprs.push_back(
nullptr);
19985 DstExprs.push_back(
nullptr);
19986 AssignmentOps.push_back(
nullptr);
19992 if (!
DSAStack->isThreadPrivate(VD)) {
19993 Diag(ELoc, diag::err_omp_required_access)
19994 << getOpenMPClauseName(OMPC_copyin)
19995 << getOpenMPDirectiveName(OMPD_threadprivate);
20010 buildVarDecl(*
this, DE->getBeginLoc(), ElemType,
".copyin.dst",
20017 BuildBinOp(
nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
20026 DSAStack->addDSA(VD, DE, OMPC_copyin);
20027 Vars.push_back(DE);
20028 SrcExprs.push_back(PseudoSrcExpr);
20029 DstExprs.push_back(PseudoDstExpr);
20030 AssignmentOps.push_back(AssignmentOp.
get());
20037 SrcExprs, DstExprs, AssignmentOps);
20048 for (
Expr *RefExpr : VarList) {
20049 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
20052 Expr *SimpleRefExpr = RefExpr;
20056 Vars.push_back(RefExpr);
20057 SrcExprs.push_back(
nullptr);
20058 DstExprs.push_back(
nullptr);
20059 AssignmentOps.push_back(
nullptr);
20066 auto *VD = dyn_cast<VarDecl>(D);
20071 if (!VD || !
DSAStack->isThreadPrivate(VD)) {
20072 DSAStackTy::DSAVarData DVar =
20074 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
20076 Diag(ELoc, diag::err_omp_wrong_dsa)
20077 << getOpenMPClauseName(DVar.CKind)
20078 << getOpenMPClauseName(OMPC_copyprivate);
20086 if (DVar.CKind == OMPC_unknown) {
20087 DVar =
DSAStack->getImplicitDSA(D,
false);
20088 if (DVar.CKind == OMPC_shared) {
20089 Diag(ELoc, diag::err_omp_required_access)
20090 << getOpenMPClauseName(OMPC_copyprivate)
20091 <<
"threadprivate or private in the enclosing context";
20100 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
20101 << getOpenMPClauseName(OMPC_copyprivate) <<
Type
20102 << getOpenMPDirectiveName(
DSAStack->getCurrentDirective());
20103 bool IsDecl = !VD || VD->isThisDeclarationADefinition(
Context) ==
20106 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
20126 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
20138 VD ? RefExpr->IgnoreParens()
20140 SrcExprs.push_back(PseudoSrcExpr);
20141 DstExprs.push_back(PseudoDstExpr);
20142 AssignmentOps.push_back(AssignmentOp.
get());
20149 Vars, SrcExprs, DstExprs, AssignmentOps);
20156 if (VarList.empty())
20164 bool Diagnose =
true) {
20165 QualType OMPDependT = Stack->getOMPDependT();
20166 if (!OMPDependT.
isNull())
20172 S.
Diag(Loc, diag::err_omp_implied_type_not_found) <<
"omp_depend_t";
20175 Stack->setOMPDependT(PT.
get());
20192 (OMPDependTFound &&
20195 Diag(Depobj->
getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
20200 Diag(Depobj->
getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
20214 if (
DSAStack->getCurrentDirective() == OMPD_ordered &&
20215 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
20216 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
20217 <<
"'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
20220 if (
DSAStack->getCurrentDirective() == OMPD_taskwait &&
20221 DepKind == OMPC_DEPEND_mutexinoutset) {
20222 Diag(DepLoc, diag::err_omp_taskwait_depend_mutexinoutset_not_allowed);
20225 if ((
DSAStack->getCurrentDirective() != OMPD_ordered ||
20226 DSAStack->getCurrentDirective() == OMPD_depobj) &&
20228 DepKind == OMPC_DEPEND_sink ||
20230 DSAStack->getCurrentDirective() == OMPD_depobj) &&
20231 DepKind == OMPC_DEPEND_depobj))) {
20233 OMPC_DEPEND_outallmemory,
20234 OMPC_DEPEND_inoutallmemory};
20235 if (
LangOpts.OpenMP < 50 ||
DSAStack->getCurrentDirective() == OMPD_depobj)
20236 Except.push_back(OMPC_DEPEND_depobj);
20238 Except.push_back(OMPC_DEPEND_inoutset);
20240 ?
"depend modifier(iterator) or "
20242 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
20246 << getOpenMPClauseName(OMPC_depend);
20250 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) {
20252 diag::err_omp_depend_sink_source_with_modifier);
20257 Diag(DepModifier->
getExprLoc(), diag::err_omp_depend_modifier_not_iterator);
20261 llvm::APSInt DepCounter(32);
20262 llvm::APSInt TotalDepCount(32);
20263 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
20264 if (
const Expr *OrderedCountExpr =
20265 DSAStack->getParentOrderedRegionParam().first) {
20266 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(
Context);
20267 TotalDepCount.setIsUnsigned(
true);
20270 for (
Expr *RefExpr : VarList) {
20271 assert(RefExpr &&
"NULL expr in OpenMP shared clause.");
20272 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
20274 Vars.push_back(RefExpr);
20280 if (DepKind == OMPC_DEPEND_sink) {
20281 if (
DSAStack->getParentOrderedRegionParam().first &&
20282 DepCounter >= TotalDepCount) {
20283 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
20297 Vars.push_back(RefExpr);
20303 Expr *LHS = SimpleExpr;
20304 Expr *RHS =
nullptr;
20305 if (
auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
20307 OOLoc = BO->getOperatorLoc();
20310 }
else if (
auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
20311 OOK = OCE->getOperator();
20312 OOLoc = OCE->getOperatorLoc();
20315 }
else if (
auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
20316 OOK = MCE->getMethodDecl()
20319 .getCXXOverloadedOperator();
20320 OOLoc = MCE->getCallee()->getExprLoc();
20329 Vars.push_back(RefExpr);
20335 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK !=
OO_None)) {
20336 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
20340 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
20341 RHS, OMPC_depend,
false);
20346 DSAStack->getParentOrderedRegionParam().first &&
20347 DepCounter !=
DSAStack->isParentLoopControlVariable(D).first) {
20349 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue());
20351 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
20354 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
20357 OpsOffs.emplace_back(RHS, OOK);
20359 bool OMPDependTFound =
LangOpts.OpenMP >= 50;
20360 if (OMPDependTFound)
20362 DepKind == OMPC_DEPEND_depobj);
20363 if (DepKind == OMPC_DEPEND_depobj) {
20367 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
20368 !RefExpr->isInstantiationDependent() &&
20369 !RefExpr->containsUnexpandedParameterPack() &&
20370 (OMPDependTFound &&
20372 RefExpr->getType()))) {
20373 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
20374 << 0 << RefExpr->getType() << RefExpr->getSourceRange();
20377 if (!RefExpr->isLValue()) {
20378 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
20379 << 1 << RefExpr->getType() << RefExpr->getSourceRange();
20386 QualType ExprTy = RefExpr->getType().getNonReferenceType();
20387 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
20391 if (
const auto *ATy = BaseType->getAsArrayTypeUnsafe())
20392 ExprTy = ATy->getElementType();
20396 const Expr *Length = OASE->getLength();
20400 Result.Val.getInt().isZero()) {
20402 diag::err_omp_depend_zero_length_array_section_not_allowed)
20412 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
20413 !RefExpr->isInstantiationDependent() &&
20414 !RefExpr->containsUnexpandedParameterPack() &&
20415 (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
20416 (OMPDependTFound &&
20418 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
20419 << (
LangOpts.OpenMP >= 50 ? 1 : 0)
20420 << (
LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
20424 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
20425 if (ASE && !ASE->getBase()->isTypeDependent() &&
20426 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() &&
20427 !ASE->getBase()->getType().getNonReferenceType()->isArrayType()) {
20428 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
20429 << (
LangOpts.OpenMP >= 50 ? 1 : 0)
20430 << (
LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
20438 RefExpr->IgnoreParenImpCasts());
20440 if (!Res.
isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
20441 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
20442 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
20443 << (
LangOpts.OpenMP >= 50 ? 1 : 0)
20444 << (
LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
20449 Vars.push_back(RefExpr->IgnoreParenImpCasts());
20453 TotalDepCount > VarList.size() &&
20454 DSAStack->getParentOrderedRegionParam().first &&
20455 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
20456 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
20457 << 1 <<
DSAStack->getParentLoopControlVariable(VarList.size() + 1);
20459 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
20460 DepKind != OMPC_DEPEND_outallmemory &&
20461 DepKind != OMPC_DEPEND_inoutallmemory && Vars.empty())
20465 Context, StartLoc, LParenLoc, EndLoc,
20467 TotalDepCount.getZExtValue());
20468 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
20469 DSAStack->isParentOrderedRegion())
20470 DSAStack->addDoacrossDependClause(
C, OpsOffs);
20480 "Unexpected device modifier in OpenMP < 50.");
20482 bool ErrorFound =
false;
20484 std::string Values =
20486 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
20487 << Values << getOpenMPClauseName(OMPC_device);
20491 Expr *ValExpr = Device;
20492 Stmt *HelperValStmt =
nullptr;
20505 if (Modifier == OMPC_DEVICE_ancestor) {
20509 diag::err_omp_device_ancestor_without_requires_reverse_offload);
20519 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
20520 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
20525 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
20526 LParenLoc, ModifierLoc, EndLoc);
20531 bool FullCheck =
true) {
20536 SemaRef.
Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
20546 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
20551 if (isa<ArraySubscriptExpr>(E) ||
20552 (OASE && OASE->getColonLocFirst().isInvalid())) {
20553 if (
const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.
getTypePtr()))
20554 return ATy->getSize().getSExtValue() != 1;
20559 assert(OASE &&
"Expecting array section if not an array subscript.");
20560 const Expr *LowerBound = OASE->getLowerBound();
20561 const Expr *Length = OASE->getLength();
20571 if (ConstLowerBound.getSExtValue())
20586 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.
getTypePtr());
20595 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
20604 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
20608 if (isa<ArraySubscriptExpr>(E) ||
20609 (OASE && OASE->getColonLocFirst().isInvalid()))
20612 assert(OASE &&
"Expecting array section if not an array subscript.");
20613 const Expr *Length = OASE->getLength();
20619 if (
const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.
getTypePtr()))
20620 return ATy->getSize().getSExtValue() != 1;
20631 return ConstLength.getSExtValue() != 1;
20670class MapBaseChecker final :
public StmtVisitor<MapBaseChecker, bool> {
20675 bool IsNonContiguous =
false;
20676 bool NoDiagnose =
false;
20677 const Expr *RelevantExpr =
nullptr;
20678 bool AllowUnitySizeArraySection =
true;
20679 bool AllowWholeSizeArraySection =
true;
20680 bool AllowAnotherPtr =
true;
20684 void emitErrorMsg() {
20686 if (SemaRef.getLangOpts().OpenMP < 50) {
20688 diag::err_omp_expected_named_var_member_or_array_expression)
20691 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
20692 << getOpenMPClauseName(CKind) << ERange;
20698 if (!isa<VarDecl>(DRE->
getDecl())) {
20702 assert(!RelevantExpr &&
"RelevantExpr is expected to be nullptr");
20703 RelevantExpr = DRE;
20705 Components.emplace_back(DRE, DRE->
getDecl(), IsNonContiguous);
20713 if (isa<CXXThisExpr>(BaseE)) {
20714 assert(!RelevantExpr &&
"RelevantExpr is expected to be nullptr");
20723 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
20739 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
20759 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
20763 return RelevantExpr || Visit(E);
20773 AllowUnitySizeArraySection =
false;
20774 AllowWholeSizeArraySection =
false;
20777 Components.emplace_back(ME, FD, IsNonContiguous);
20778 return RelevantExpr || Visit(E);
20786 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
20790 return RelevantExpr || Visit(E);
20797 AllowWholeSizeArraySection =
false;
20803 !Result.Val.getInt().isZero()) {
20805 diag::err_omp_invalid_map_this_expr);
20807 diag::note_omp_invalid_subscript_on_this_ptr_map);
20809 assert(!RelevantExpr &&
"RelevantExpr is expected to be nullptr");
20814 Components.emplace_back(AE,
nullptr, IsNonContiguous);
20816 return RelevantExpr || Visit(E);
20822 assert(!(SemaRef.getLangOpts().OpenMP < 50 && NoDiagnose) &&
20823 "Array sections cannot be implicitly mapped.");
20837 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
20847 if (AllowWholeSizeArraySection) {
20854 if (NotWhole || IsPointer)
20855 AllowWholeSizeArraySection =
false;
20856 }
else if (DKind == OMPD_target_update &&
20857 SemaRef.getLangOpts().OpenMP >= 50) {
20858 if (IsPointer && !AllowAnotherPtr)
20859 SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined)
20862 IsNonContiguous =
true;
20863 }
else if (AllowUnitySizeArraySection && NotUnity) {
20869 diag::err_array_section_does_not_specify_contiguous_storage)
20875 AllowAnotherPtr =
false;
20877 if (
const auto *TE = dyn_cast<CXXThisExpr>(E)) {
20884 diag::err_omp_invalid_map_this_expr);
20886 diag::note_omp_invalid_length_on_this_ptr_mapping);
20890 SemaRef.getASTContext()) &&
20893 diag::err_omp_invalid_map_this_expr);
20895 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
20897 assert(!RelevantExpr &&
"RelevantExpr is expected to be nullptr");
20902 Components.emplace_back(OASE,
nullptr,
false);
20903 return RelevantExpr || Visit(E);
20909 Components.emplace_back(E,
nullptr, IsNonContiguous);
20911 return Visit(
Base->IgnoreParenImpCasts());
20915 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->
isLValue() ||
20920 if (!RelevantExpr) {
20922 Components.emplace_back(UO,
nullptr,
false);
20938 Components.emplace_back(BO,
nullptr,
false);
20941 "Either LHS or RHS have base decl inside");
20943 return RelevantExpr || Visit(LE);
20944 return RelevantExpr || Visit(RE);
20947 assert(!RelevantExpr &&
"RelevantExpr is expected to be nullptr");
20948 RelevantExpr = CTE;
20949 Components.emplace_back(CTE,
nullptr, IsNonContiguous);
20953 assert(!RelevantExpr &&
"RelevantExpr is expected to be nullptr");
20954 Components.emplace_back(COCE,
nullptr, IsNonContiguous);
20963 return Visit(Source);
20965 bool VisitStmt(
Stmt *) {
20969 const Expr *getFoundBase()
const {
return RelevantExpr; }
20970 explicit MapBaseChecker(
20974 : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components),
20975 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {}
20989 MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc,
20993 if (SemaRef.
getLangOpts().OpenMP >= 50 && !CurComponents.empty() &&
20994 (CKind == OMPC_to || CKind == OMPC_from)) {
20995 auto CI = CurComponents.rbegin();
20996 auto CE = CurComponents.rend();
20997 for (; CI != CE; ++CI) {
20999 dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression());
21004 SemaRef.
Diag(ELoc, diag::err_array_section_does_not_specify_length)
21008 return Checker.getFoundBase();
21017 bool CurrentRegionOnly,
21028 assert(!CurComponents.empty() &&
"Map clause expression with no components!");
21029 assert(CurComponents.back().getAssociatedDeclaration() == VD &&
21030 "Map clause expression with unexpected base!");
21033 bool IsEnclosedByDataEnvironmentExpr =
false;
21034 const Expr *EnclosingExpr =
nullptr;
21036 bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
21037 VD, CurrentRegionOnly,
21038 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
21039 ERange, CKind, &EnclosingExpr,
21043 if (CKind == Kind && SemaRef.
LangOpts.OpenMP >= 50)
21045 assert(!StackComponents.empty() &&
21046 "Map clause expression with no components!");
21047 assert(StackComponents.back().getAssociatedDeclaration() == VD &&
21048 "Map clause expression with unexpected base!");
21052 const Expr *RE = StackComponents.front().getAssociatedExpression();
21058 auto CI = CurComponents.rbegin();
21059 auto CE = CurComponents.rend();
21060 auto SI = StackComponents.rbegin();
21061 auto SE = StackComponents.rend();
21062 for (; CI != CE && SI != SE; ++CI, ++SI) {
21067 if (CurrentRegionOnly &&
21068 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
21069 isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) ||
21070 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) &&
21071 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
21072 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) ||
21073 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) {
21074 SemaRef.
Diag(CI->getAssociatedExpression()->getExprLoc(),
21075 diag::err_omp_multiple_array_items_in_map_clause)
21076 << CI->getAssociatedExpression()->getSourceRange();
21077 SemaRef.
Diag(SI->getAssociatedExpression()->getExprLoc(),
21078 diag::note_used_here)
21079 << SI->getAssociatedExpression()->getSourceRange();
21084 if (CI->getAssociatedExpression()->getStmtClass() !=
21085 SI->getAssociatedExpression()->getStmtClass())
21089 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
21095 for (; SI != SE; ++SI) {
21097 if (
const auto *ASE =
21098 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
21099 Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
21100 }
else if (
const auto *OASE = dyn_cast<OMPArraySectionExpr>(
21101 SI->getAssociatedExpression())) {
21105 }
else if (
const auto *OASE = dyn_cast<OMPArrayShapingExpr>(
21106 SI->getAssociatedExpression())) {
21111 SemaRef, SI->getAssociatedExpression(),
Type))
21121 if (CI == CE && SI == SE) {
21122 if (CurrentRegionOnly) {
21123 if (CKind == OMPC_map) {
21124 SemaRef.
Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
21126 assert(CKind == OMPC_to || CKind == OMPC_from);
21127 SemaRef.
Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
21136 IsEnclosedByDataEnvironmentExpr =
true;
21141 std::prev(CI)->getAssociatedDeclaration()->getType();
21143 std::prev(CI)->getAssociatedExpression()->getExprLoc();
21162 if (CI == CE || SI == SE) {
21165 diag::err_omp_pointer_mapped_along_with_derived_section)
21171 if (CI->getAssociatedExpression()->getStmtClass() !=
21172 SI->getAssociatedExpression()->getStmtClass() ||
21173 CI->getAssociatedDeclaration()->getCanonicalDecl() ==
21174 SI->getAssociatedDeclaration()->getCanonicalDecl()) {
21175 assert(CI != CE && SI != SE);
21176 SemaRef.
Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
21189 if (CurrentRegionOnly && (CI == CE || SI == SE)) {
21190 if (CKind == OMPC_map) {
21191 if (CI != CE || SI != SE) {
21195 CI != CE ? CurComponents.begin() : StackComponents.begin();
21196 auto End = CI != CE ? CurComponents.end() : StackComponents.end();
21198 while (It != End && !It->getAssociatedDeclaration())
21199 std::advance(It, 1);
21200 assert(It != End &&
21201 "Expected at least one component with the declaration.");
21202 if (It !=
Begin && It->getAssociatedDeclaration()
21204 .getCanonicalType()
21205 ->isAnyPointerType()) {
21206 IsEnclosedByDataEnvironmentExpr =
false;
21207 EnclosingExpr =
nullptr;
21211 SemaRef.
Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
21213 assert(CKind == OMPC_to || CKind == OMPC_from);
21214 SemaRef.
Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
21224 if (!CurrentRegionOnly && SI != SE)
21225 EnclosingExpr = RE;
21229 IsEnclosedByDataEnvironmentExpr |=
21230 (!CurrentRegionOnly && CI != CE && SI == SE);
21235 if (CurrentRegionOnly)
21249 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
21251 diag::err_omp_original_storage_is_shared_and_does_not_contain)
21267 Expr *UnresolvedMapper) {
21282 while (S && !S->isDeclScope(D))
21283 S = S->getParent();
21285 S = S->getParent();
21286 Lookups.emplace_back();
21287 Lookups.back().append(Lookup.
begin(), Lookup.
end());
21290 }
else if (
auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
21295 assert(DMD &&
"Expect valid OMPDeclareMapperDecl during instantiation.");
21296 Lookups.back().addDecl(DMD);
21305 return !D->isInvalidDecl() &&
21306 (D->getType()->isDependentType() ||
21307 D->getType()->isInstantiationDependentType() ||
21308 D->getType()->containsUnexpandedParameterPack());
21314 URS.
append(Set.begin(), Set.end());
21319 false,
true, URS.
begin(), URS.
end());
21326 SemaRef.
Diag(Loc, diag::err_omp_mapper_wrong_type);
21366 SemaRef.
Diag(Loc, diag::err_omp_invalid_mapper)
21376struct MappableVarListInfo {
21391 VarComponents.reserve(VarList.size());
21392 VarBaseDeclarations.reserve(VarList.size());
21410 bool IsMapTypeImplicit =
false,
bool NoDiagnose =
false) {
21412 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
21413 "Unexpected clause kind with mappable expressions!");
21421 MapperId.
setName(DeclNames.getIdentifier(
21423 MapperId.
setLoc(StartLoc);
21427 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
21428 bool UpdateUMIt =
false;
21429 Expr *UnresolvedMapper =
nullptr;
21431 bool HasHoldModifier =
21432 llvm::is_contained(Modifiers, OMPC_MAP_MODIFIER_ompx_hold);
21440 for (
Expr *RE : MVLI.VarList) {
21441 assert(RE &&
"Null expr in omp to/from/map clause");
21445 if (UpdateUMIt && UMIt != UMEnd) {
21449 "Expect the size of UnresolvedMappers to match with that of VarList");
21453 UnresolvedMapper = *UMIt;
21462 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
21466 MVLI.UDMapperList.push_back(ER.
get());
21469 MVLI.ProcessedVarList.push_back(RE);
21478 ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
21481 SemaRef.
Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
21494 DSAS->getCurrentDirective(), NoDiagnose);
21498 assert(!CurComponents.empty() &&
21499 "Invalid mappable expression information.");
21501 if (
const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
21503 DSAS->addMappedClassesQualTypes(TE->getType());
21506 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
21510 MVLI.UDMapperList.push_back(ER.
get());
21512 MVLI.ProcessedVarList.push_back(RE);
21513 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
21514 MVLI.VarComponents.back().append(CurComponents.begin(),
21515 CurComponents.end());
21516 MVLI.VarBaseDeclarations.push_back(
nullptr);
21523 CurDeclaration = CurComponents.back().getAssociatedDeclaration();
21524 assert(CurDeclaration &&
"Null decl on map clause.");
21527 "Expecting components to have associated only canonical declarations.");
21529 auto *VD = dyn_cast<VarDecl>(CurDeclaration);
21530 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
21532 assert((VD || FD) &&
"Only variables or fields are expected here!");
21539 if (VD && DSAS->isThreadPrivate(VD)) {
21542 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD,
false);
21543 SemaRef.
Diag(ELoc, diag::err_omp_threadprivate_in_clause)
21544 << getOpenMPClauseName(CKind);
21558 true, CurComponents, CKind))
21560 if (CKind == OMPC_map &&
21563 false, CurComponents, CKind))
21570 auto I = llvm::find_if(
21575 assert(I != CurComponents.end() &&
"Null decl on map clause.");
21578 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->
IgnoreParens());
21579 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->
IgnoreParens());
21580 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->
IgnoreParens());
21582 Type = ASE->getType().getNonReferenceType();
21586 if (
const auto *ATy = BaseType->getAsArrayTypeUnsafe())
21587 Type = ATy->getElementType();
21590 Type =
Type.getNonReferenceType();
21591 }
else if (OAShE) {
21605 if (CKind == OMPC_map) {
21611 if (DKind == OMPD_target_enter_data &&
21612 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
21613 SemaRef.
Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
21614 << (IsMapTypeImplicit ? 1 : 0)
21616 << getOpenMPDirectiveName(DKind);
21624 if (DKind == OMPD_target_exit_data &&
21625 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
21626 MapType == OMPC_MAP_delete)) {
21627 SemaRef.
Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
21628 << (IsMapTypeImplicit ? 1 : 0)
21630 << getOpenMPDirectiveName(DKind);
21639 if ((DKind == OMPD_target_enter_data || DKind == OMPD_target_exit_data) &&
21641 SemaRef.
Diag(StartLoc,
21642 diag::err_omp_invalid_map_type_modifier_for_directive)
21644 OMPC_MAP_MODIFIER_ompx_hold)
21645 << getOpenMPDirectiveName(DKind);
21653 if ((DKind == OMPD_target_data ||
21655 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
21656 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) {
21657 SemaRef.
Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
21658 << (IsMapTypeImplicit ? 1 : 0)
21660 << getOpenMPDirectiveName(DKind);
21672 if (VD && ((SemaRef.
LangOpts.OpenMP <= 45 &&
21674 DKind == OMPD_target)) {
21675 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD,
false);
21677 SemaRef.
Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
21678 << getOpenMPClauseName(DVar.CKind)
21679 << getOpenMPClauseName(OMPC_map)
21680 << getOpenMPDirectiveName(DSAS->getCurrentDirective());
21689 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
21690 Type.getCanonicalType(), UnresolvedMapper);
21693 MVLI.UDMapperList.push_back(ER.
get());
21696 MVLI.ProcessedVarList.push_back(RE);
21700 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
21706 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
21707 MVLI.VarComponents.back().append(CurComponents.begin(),
21708 CurComponents.end());
21709 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ?
nullptr
21729 unsigned Count = 0;
21730 for (
unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
21732 llvm::is_contained(Modifiers, MapTypeModifiers[I])) {
21733 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
21737 "Modifiers exceed the allowed number of map type modifiers");
21738 Modifiers[Count] = MapTypeModifiers[I];
21739 ModifiersLoc[Count] = MapTypeModifiersLoc[I];
21743 MappableVarListInfo MVLI(VarList);
21745 MapperIdScopeSpec, MapperId, UnresolvedMappers,
21746 MapType, Modifiers, IsMapTypeImplicit,
21752 MVLI.VarBaseDeclarations, MVLI.VarComponents,
21753 MVLI.UDMapperList, Modifiers, ModifiersLoc,
21755 MapperId, MapType, IsMapTypeImplicit, MapLoc);
21763 if (ReductionType.
isNull())
21771 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
21776 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
21780 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
21784 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
21787 return ReductionType;
21792 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
21795 Decls.reserve(ReductionTypes.size());
21803 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
21805 bool InCompoundScope =
true;
21806 if (S !=
nullptr) {
21815 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
21817 while (Filter.hasNext()) {
21819 if (InCompoundScope) {
21820 auto I = UsedAsPrevious.find(PrevDecl);
21821 if (I == UsedAsPrevious.end())
21822 UsedAsPrevious[PrevDecl] =
false;
21824 UsedAsPrevious[D] =
true;
21826 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
21827 PrevDecl->getLocation();
21830 if (InCompoundScope) {
21831 for (
const auto &PrevData : UsedAsPrevious) {
21832 if (!PrevData.second) {
21833 PrevDRD = PrevData.first;
21838 }
else if (PrevDeclInScope !=
nullptr) {
21839 auto *PrevDRDInScope = PrevDRD =
21842 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
21843 PrevDRDInScope->getLocation();
21844 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
21845 }
while (PrevDRDInScope !=
nullptr);
21847 for (
const auto &TyData : ReductionTypes) {
21848 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
21850 if (I != PreviousRedeclTypes.end()) {
21851 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
21853 Diag(I->second, diag::note_previous_definition);
21856 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
21858 Name, TyData.first, PrevDRD);
21860 DRD->setAccess(AS);
21861 Decls.push_back(DRD);
21863 DRD->setInvalidDecl();
21888 QualType ReductionType = DRD->getType();
21905 if (S !=
nullptr) {
21909 DRD->addDecl(OmpInParm);
21910 DRD->addDecl(OmpOutParm);
21916 DRD->setCombinerData(InE, OutE);
21927 if (Combiner !=
nullptr)
21928 DRD->setCombiner(Combiner);
21930 DRD->setInvalidDecl();
21948 QualType ReductionType = DRD->getType();
21965 if (S !=
nullptr) {
21969 DRD->addDecl(OmpPrivParm);
21970 DRD->addDecl(OmpOrigParm);
21976 DRD->setInitializerData(OrigE, PrivE);
21977 return OmpPrivParm;
21991 }
else if (OmpPrivParm->
hasInit()) {
21992 DRD->setInitializer(OmpPrivParm->
getInit(),
21997 DRD->setInvalidDecl();
22003 for (
Decl *D : DeclReductions.
get()) {
22009 D->setInvalidDecl();
22012 return DeclReductions;
22031 assert(
ParsedType.isUsable() &&
"Expect usable parsed mapper type");
22034 assert(!MapperType.
isNull() &&
"Expect valid mapper type");
22039 Diag(TyLoc, diag::err_omp_mapper_wrong_type);
22055 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
22057 bool InCompoundScope =
true;
22058 if (S !=
nullptr) {
22067 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
22069 while (Filter.hasNext()) {
22071 if (InCompoundScope) {
22072 auto I = UsedAsPrevious.find(PrevDecl);
22073 if (I == UsedAsPrevious.end())
22074 UsedAsPrevious[PrevDecl] =
false;
22076 UsedAsPrevious[D] =
true;
22078 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
22079 PrevDecl->getLocation();
22082 if (InCompoundScope) {
22083 for (
const auto &PrevData : UsedAsPrevious) {
22084 if (!PrevData.second) {
22085 PrevDMD = PrevData.first;
22090 }
else if (PrevDeclInScope) {
22091 auto *PrevDMDInScope = PrevDMD =
22094 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
22095 PrevDMDInScope->getLocation();
22096 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
22097 }
while (PrevDMDInScope !=
nullptr);
22101 if (I != PreviousRedeclTypes.end()) {
22102 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
22103 << MapperType << Name;
22104 Diag(I->second, diag::note_previous_definition);
22115 ClausesWithImplicit, PrevDMD);
22120 DMD->setAccess(AS);
22122 DMD->setInvalidDecl();
22128 DMD->setMapperVarRef(MapperVarRef);
22145 DSAStack->addDeclareMapperVarRef(E);
22150 assert(
LangOpts.OpenMP &&
"Expected OpenMP mode.");
22152 if (
const auto *DRE = cast_or_null<DeclRefExpr>(Ref)) {
22163 assert(
LangOpts.OpenMP &&
"Expected OpenMP mode.");
22171 Expr *ValExpr = NumTeams;
22172 Stmt *HelperValStmt =
nullptr;
22185 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
22186 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
22191 StartLoc, LParenLoc, EndLoc);
22198 Expr *ValExpr = ThreadLimit;
22199 Stmt *HelperValStmt =
nullptr;
22209 DKind, OMPC_thread_limit,
LangOpts.OpenMP);
22212 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
22213 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
22218 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
22226 Stmt *HelperValStmt =
nullptr;
22232 ValExpr, *
this, OMPC_priority,
22234 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
22238 StartLoc, LParenLoc, EndLoc);
22245 Expr *ValExpr = Grainsize;
22246 Stmt *HelperValStmt =
nullptr;
22253 ValExpr, *
this, OMPC_grainsize,
22255 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
22259 StartLoc, LParenLoc, EndLoc);
22266 Expr *ValExpr = NumTasks;
22267 Stmt *HelperValStmt =
nullptr;
22274 ValExpr, *
this, OMPC_num_tasks,
22276 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
22280 StartLoc, LParenLoc, EndLoc);
22290 VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint,
false);
22299 DSAStackTy *Stack) {
22300 QualType OMPEventHandleT = Stack->getOMPEventHandleT();
22301 if (!OMPEventHandleT.
isNull())
22306 S.
Diag(Loc, diag::err_omp_implied_type_not_found) <<
"omp_event_handle_t";
22309 Stack->setOMPEventHandleT(PT.
get());
22329 auto *VD = dyn_cast_or_null<VarDecl>(Ref->
getDecl());
22339 <<
"omp_event_handle_t" << 1 << VD->
getType()
22346 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(VD,
false);
22347 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
22350 << getOpenMPClauseName(DVar.CKind)
22351 << getOpenMPClauseName(OMPC_firstprivate);
22365 std::string Values;
22369 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
22370 << Values << getOpenMPClauseName(OMPC_dist_schedule);
22373 Expr *ValExpr = ChunkSize;
22374 Stmt *HelperValStmt =
nullptr;
22385 ValExpr = Val.
get();
22392 if (
Result->isSigned() && !
Result->isStrictlyPositive()) {
22393 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
22398 DSAStack->getCurrentDirective(), OMPC_dist_schedule,
22399 LangOpts.OpenMP) != OMPD_unknown &&
22402 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
22403 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
22411 Kind, ValExpr, HelperValStmt);
22419 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
22420 Kind != OMPC_DEFAULTMAP_scalar) {
22424 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
22426 OMPC_DEFAULTMAP_MODIFIER_tofrom);
22430 OMPC_DEFAULTMAP_scalar);
22434 Diag(Loc, diag::err_omp_unexpected_clause_value)
22435 <<
Value << getOpenMPClauseName(OMPC_defaultmap);
22442 if (!isDefaultmapKind || !isDefaultmapModifier) {
22443 StringRef KindValue =
"'scalar', 'aggregate', 'pointer'";
22445 StringRef ModifierValue =
"'alloc', 'from', 'to', 'tofrom', "
22446 "'firstprivate', 'none', 'default'";
22447 if (!isDefaultmapKind && isDefaultmapModifier) {
22448 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
22449 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
22450 }
else if (isDefaultmapKind && !isDefaultmapModifier) {
22451 Diag(MLoc, diag::err_omp_unexpected_clause_value)
22452 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
22454 Diag(MLoc, diag::err_omp_unexpected_clause_value)
22455 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
22456 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
22457 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
22460 StringRef ModifierValue =
22461 "'alloc', 'from', 'to', 'tofrom', "
22462 "'firstprivate', 'none', 'default', 'present'";
22463 if (!isDefaultmapKind && isDefaultmapModifier) {
22464 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
22465 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
22466 }
else if (isDefaultmapKind && !isDefaultmapModifier) {
22467 Diag(MLoc, diag::err_omp_unexpected_clause_value)
22468 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
22470 Diag(MLoc, diag::err_omp_unexpected_clause_value)
22471 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
22472 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
22473 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
22482 if (
DSAStack->checkDefaultmapCategory(Kind)) {
22483 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category);
22489 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc);
22490 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc);
22491 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc);
22493 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc);
22501 DeclareTargetContextInfo &DTCI) {
22506 !isa<CXXRecordDecl>(CurLexicalContext) &&
22507 !isa<ClassTemplateDecl>(CurLexicalContext) &&
22508 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
22509 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
22510 Diag(DTCI.Loc, diag::err_omp_region_not_file_context);
22513 DeclareTargetNesting.push_back(DTCI);
22517const Sema::DeclareTargetContextInfo
22519 assert(!DeclareTargetNesting.empty() &&
22520 "check isInOpenMPDeclareTargetContext() first!");
22521 return DeclareTargetNesting.pop_back_val();
22525 DeclareTargetContextInfo &DTCI) {
22526 for (
auto &It : DTCI.ExplicitlyMapped)
22531 if (DeclareTargetNesting.empty())
22533 DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back();
22534 Diag(DTCI.Loc, diag::warn_omp_unterminated_declare_target)
22535 << getOpenMPDirectiveName(DTCI.Kind);
22549 VarOrFuncDeclFilterCCC CCC(*
this);
22559 Diag(
Id.getLoc(), diag::err_undeclared_var_use) <<
Id.getName();
22564 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
22565 !isa<FunctionTemplateDecl>(ND)) {
22566 Diag(
Id.getLoc(), diag::err_omp_invalid_target_decl) <<
Id.getName();
22573 OMPDeclareTargetDeclAttr::MapTypeTy MT,
22574 DeclareTargetContextInfo &DTCI) {
22575 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||
22576 isa<FunctionTemplateDecl>(ND)) &&
22577 "Expected variable, function or function template.");
22583 Diag(Loc, diag::warn_omp_declare_target_after_first_use);
22586 const unsigned Level = -1;
22590 OMPDeclareTargetDeclAttr::getActiveAttr(VD);
22591 if (ActiveAttr && ActiveAttr.value()->getDevType() != DTCI.DT &&
22592 ActiveAttr.value()->getLevel() == Level) {
22593 Diag(Loc, diag::err_omp_device_type_mismatch)
22594 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DTCI.DT)
22595 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(
22596 ActiveAttr.value()->getDevType());
22599 if (ActiveAttr && ActiveAttr.value()->getMapType() != MT &&
22600 ActiveAttr.value()->getLevel() == Level) {
22601 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
22605 if (ActiveAttr && ActiveAttr.value()->getLevel() == Level)
22608 Expr *IndirectE =
nullptr;
22609 bool IsIndirect =
false;
22610 if (DTCI.Indirect) {
22611 IndirectE = DTCI.Indirect.value();
22615 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
22616 Context, MT, DTCI.DT, IndirectE, IsIndirect, Level,
22620 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
22626 if (!D || !isa<VarDecl>(D))
22630 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
22631 if (SemaRef.
LangOpts.OpenMP >= 50 &&
22634 VD->hasGlobalStorage()) {
22635 if (!
MapTy || *
MapTy != OMPDeclareTargetDeclAttr::MT_To) {
22642 diag::err_omp_lambda_capture_in_declare_target_not_to);
22643 SemaRef.
Diag(SL, diag::note_var_explicitly_captured_here)
22650 SemaRef.
Diag(VD->
getLocation(), diag::warn_omp_not_in_target_context);
22651 SemaRef.
Diag(SL, diag::note_used_here) << SR;
22655 Sema &SemaRef, DSAStackTy *Stack,
22657 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
22668 if (
auto *VD = dyn_cast<VarDecl>(D)) {
22670 if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
22671 !VD->isStaticDataMember())
22675 if (
DSAStack->isThreadPrivate(VD)) {
22676 Diag(SL, diag::err_omp_threadprivate_in_target);
22681 if (
const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
22682 D = FTD->getTemplatedDecl();
22683 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
22685 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
22686 if (IdLoc.
isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
22687 Diag(IdLoc, diag::err_omp_function_in_link_clause);
22692 if (
auto *VD = dyn_cast<ValueDecl>(D)) {
22700 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
22701 isa<FunctionTemplateDecl>(D)) {
22703 OMPDeclareTargetDeclAttr::getActiveAttr(VD);
22704 unsigned Level = DeclareTargetNesting.size();
22705 if (ActiveAttr && ActiveAttr.value()->getLevel() >= Level)
22707 DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back();
22708 Expr *IndirectE =
nullptr;
22709 bool IsIndirect =
false;
22710 if (DTCI.Indirect) {
22711 IndirectE = DTCI.Indirect.value();
22715 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
22716 Context, OMPDeclareTargetDeclAttr::MT_To, DTCI.DT, IndirectE,
22717 IsIndirect, Level,
SourceRange(DTCI.Loc, DTCI.Loc));
22720 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
22741 unsigned Count = 0;
22742 for (
unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
22744 llvm::is_contained(Modifiers, MotionModifiers[I])) {
22745 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
22749 "Modifiers exceed the allowed number of motion modifiers");
22750 Modifiers[Count] = MotionModifiers[I];
22751 ModifiersLoc[Count] = MotionModifiersLoc[I];
22755 MappableVarListInfo MVLI(VarList);
22757 MapperIdScopeSpec, MapperId, UnresolvedMappers);
22758 if (MVLI.ProcessedVarList.empty())
22762 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
22763 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
22778 unsigned Count = 0;
22779 for (
unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
22781 llvm::is_contained(Modifiers, MotionModifiers[I])) {
22782 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
22786 "Modifiers exceed the allowed number of motion modifiers");
22787 Modifiers[Count] = MotionModifiers[I];
22788 ModifiersLoc[Count] = MotionModifiersLoc[I];
22792 MappableVarListInfo MVLI(VarList);
22794 MapperIdScopeSpec, MapperId, UnresolvedMappers);
22795 if (MVLI.ProcessedVarList.empty())
22799 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
22800 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
22806 MappableVarListInfo MVLI(VarList);
22810 for (
Expr *RefExpr : VarList) {
22811 assert(RefExpr &&
"NULL expr in OpenMP use_device_ptr clause.");
22814 Expr *SimpleRefExpr = RefExpr;
22818 MVLI.ProcessedVarList.push_back(RefExpr);
22819 PrivateCopies.push_back(
nullptr);
22820 Inits.push_back(
nullptr);
22827 Type =
Type.getNonReferenceType().getUnqualifiedType();
22829 auto *VD = dyn_cast<VarDecl>(D);
22833 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
22834 << 0 << RefExpr->getSourceRange();
22842 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
22843 if (VDPrivate->isInvalidDecl())
22848 *
this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
22854 *
this, VDInit, RefExpr->
getType(), RefExpr->getExprLoc());
22864 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
22865 PrivateCopies.push_back(VDPrivateRefExpr);
22866 Inits.push_back(VDInitRefExpr);
22871 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
22875 MVLI.VarBaseDeclarations.push_back(D);
22876 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
22877 MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D,
22881 if (MVLI.ProcessedVarList.empty())
22885 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
22886 MVLI.VarBaseDeclarations, MVLI.VarComponents);
22891 MappableVarListInfo MVLI(VarList);
22893 for (
Expr *RefExpr : VarList) {
22894 assert(RefExpr &&
"NULL expr in OpenMP use_device_addr clause.");
22897 Expr *SimpleRefExpr = RefExpr;
22902 MVLI.ProcessedVarList.push_back(RefExpr);
22907 auto *VD = dyn_cast<VarDecl>(D);
22914 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
22919 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
22923 MVLI.VarBaseDeclarations.push_back(D);
22924 MVLI.VarComponents.emplace_back();
22925 Expr *Component = SimpleRefExpr;
22926 if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
22927 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
22929 MVLI.VarComponents.back().emplace_back(Component, D,
22933 if (MVLI.ProcessedVarList.empty())
22937 MVLI.VarBaseDeclarations,
22938 MVLI.VarComponents);
22943 MappableVarListInfo MVLI(VarList);
22944 for (
Expr *RefExpr : VarList) {
22945 assert(RefExpr &&
"NULL expr in OpenMP is_device_ptr clause.");
22948 Expr *SimpleRefExpr = RefExpr;
22952 MVLI.ProcessedVarList.push_back(RefExpr);
22962 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
22963 << 0 << RefExpr->getSourceRange();
22969 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
22971 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
22972 << getOpenMPClauseName(DVar.CKind)
22973 << getOpenMPClauseName(OMPC_is_device_ptr)
22974 << getOpenMPDirectiveName(
DSAStack->getCurrentDirective());
22979 const Expr *ConflictExpr;
22980 if (
DSAStack->checkMappableExprComponentListsForDecl(
22985 ConflictExpr = R.front().getAssociatedExpression();
22988 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
22997 SimpleRefExpr, D,
false);
22998 DSAStack->addMappableExpressionComponents(
22999 D, MC, OMPC_is_device_ptr);
23002 MVLI.ProcessedVarList.push_back(SimpleRefExpr);
23007 assert((isa<DeclRefExpr>(SimpleRefExpr) ||
23008 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
23009 "Unexpected device pointer expression!");
23010 MVLI.VarBaseDeclarations.push_back(
23011 isa<DeclRefExpr>(SimpleRefExpr) ? D :
nullptr);
23012 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
23013 MVLI.VarComponents.back().push_back(MC);
23016 if (MVLI.ProcessedVarList.empty())
23020 MVLI.VarBaseDeclarations,
23021 MVLI.VarComponents);
23026 MappableVarListInfo MVLI(VarList);
23027 for (
Expr *RefExpr : VarList) {
23028 assert(RefExpr &&
"NULL expr in OpenMP has_device_addr clause.");
23031 Expr *SimpleRefExpr = RefExpr;
23036 MVLI.ProcessedVarList.push_back(RefExpr);
23044 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
23046 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
23047 << getOpenMPClauseName(DVar.CKind)
23048 << getOpenMPClauseName(OMPC_has_device_addr)
23049 << getOpenMPDirectiveName(
DSAStack->getCurrentDirective());
23054 const Expr *ConflictExpr;
23055 if (
DSAStack->checkMappableExprComponentListsForDecl(
23060 ConflictExpr = R.front().getAssociatedExpression();
23063 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
23072 SimpleRefExpr, D,
false);
23073 DSAStack->addMappableExpressionComponents(
23074 D, MC, OMPC_has_device_addr);
23077 auto *VD = dyn_cast<VarDecl>(D);
23081 assert(Ref &&
"has_device_addr capture failed");
23082 MVLI.ProcessedVarList.push_back(Ref);
23084 MVLI.ProcessedVarList.push_back(RefExpr->IgnoreParens());
23089 assert((isa<DeclRefExpr>(SimpleRefExpr) ||
23090 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
23091 "Unexpected device pointer expression!");
23092 MVLI.VarBaseDeclarations.push_back(
23093 isa<DeclRefExpr>(SimpleRefExpr) ? D :
nullptr);
23094 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
23095 MVLI.VarComponents.back().push_back(MC);
23098 if (MVLI.ProcessedVarList.empty())
23102 MVLI.VarBaseDeclarations,
23103 MVLI.VarComponents);
23119 DSAStack->getOMPAllocatorHandleT(),
23124 Allocator = AllocatorRes.
get();
23133 targetDiag(StartLoc, diag::err_expected_allocator_expression);
23137 for (
Expr *RefExpr : VarList) {
23138 assert(RefExpr &&
"NULL expr in OpenMP private clause.");
23141 Expr *SimpleRefExpr = RefExpr;
23145 Vars.push_back(RefExpr);
23151 auto *VD = dyn_cast<VarDecl>(D);
23156 ? RefExpr->IgnoreParens()
23164 DSAStack->addInnerAllocatorExpr(Allocator);
23166 ColonLoc, EndLoc, Vars);
23174 for (
Expr *RefExpr : VarList) {
23175 assert(RefExpr &&
"NULL expr in OpenMP nontemporal clause.");
23178 Expr *SimpleRefExpr = RefExpr;
23182 Vars.push_back(RefExpr);
23189 if (
const Expr *PrevRef =
23190 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) {
23191 Diag(ELoc, diag::err_omp_used_in_clause_twice)
23192 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange;
23193 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
23194 << getOpenMPClauseName(OMPC_nontemporal);
23198 Vars.push_back(RefExpr);
23213 for (
Expr *RefExpr : VarList) {
23214 assert(RefExpr &&
"NULL expr in OpenMP nontemporal clause.");
23217 Expr *SimpleRefExpr = RefExpr;
23222 Vars.push_back(RefExpr);
23227 const DSAStackTy::DSAVarData DVar =
23233 if (DVar.CKind != OMPC_reduction || DVar.Modifier != OMPC_REDUCTION_inscan)
23234 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
23235 << RefExpr->getSourceRange();
23237 if (
DSAStack->getParentDirective() != OMPD_unknown)
23238 DSAStack->markDeclAsUsedInScanDirective(D);
23239 Vars.push_back(RefExpr);
23253 for (
Expr *RefExpr : VarList) {
23254 assert(RefExpr &&
"NULL expr in OpenMP nontemporal clause.");
23257 Expr *SimpleRefExpr = RefExpr;
23262 Vars.push_back(RefExpr);
23268 DSAStackTy::DSAVarData DVar;
23269 if (ParentDirective != OMPD_unknown)
23270 DVar =
DSAStack->getTopDSA(D,
true);
23275 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction ||
23276 DVar.Modifier != OMPC_REDUCTION_inscan) {
23277 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
23278 << RefExpr->getSourceRange();
23280 DSAStack->markDeclAsUsedInScanDirective(D);
23282 Vars.push_back(RefExpr);
23293 QualType OMPAlloctraitT = Stack->getOMPAlloctraitT();
23294 if (!OMPAlloctraitT.
isNull())
23299 S.
Diag(Loc, diag::err_omp_implied_type_not_found) <<
"omp_alloctrait_t";
23302 Stack->setOMPAlloctraitT(PT.
get());
23321 for (
int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
23322 auto AllocatorKind =
static_cast<OMPAllocateDeclAttr::AllocatorTypeTy
>(I);
23323 StringRef Allocator =
23324 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
23332 Expr *AllocatorExpr =
nullptr;
23340 auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr);
23341 bool IsPredefinedAllocator =
false;
23343 IsPredefinedAllocator = PredefinedAllocators.count(DRE->
getDecl());
23348 DSAStack->getOMPAllocatorHandleT(),
23350 (!IsPredefinedAllocator &&
23354 <<
"omp_allocator_handle_t" << (DRE ? 1 : 0)
23363 diag::err_omp_predefined_allocator_with_traits)
23375 diag::err_omp_nonpredefined_allocator_without_traits);
23383 IsPredefinedAllocator
23384 ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator
23385 : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator);
23387 Expr *AllocatorTraitsExpr =
nullptr;
23401 if (
const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty))
23402 TraitTy = ConstArrayTy->getElementType();
23409 diag::err_omp_expected_array_alloctraits)
23410 << AllocatorTraitsExpr->
getType();
23415 if (
auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr))
23418 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait);
23435 for (
Expr *RefExpr : Locators) {
23436 assert(RefExpr &&
"NULL expr in OpenMP shared clause.");
23437 if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) {
23439 Vars.push_back(RefExpr);
23447 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
23448 << 1 << 0 << RefExpr->getSourceRange();
23457 if (!Res.
isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
23458 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
23459 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
23460 << 1 << 0 << RefExpr->getSourceRange();
23463 Vars.push_back(SimpleExpr);
23467 EndLoc, Modifier, Vars);
23476 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23479 << getOpenMPClauseName(OMPC_bind);
Defines the clang::ASTContext interface.
llvm::Expected< T > Expected
static CompilationDatabasePluginRegistry::Add< FixedCompilationDatabasePlugin > X("fixed-compilation-database", "Reads plain-text flags file")
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
This file defines OpenMP nodes for declarative directives.
static const Decl * getCanonicalDecl(const Decl *D)
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
This file defines OpenMP AST classes for clauses.
Defines some OpenMP-specific enums and functions.
llvm::DenseMap< Stmt *, Stmt * > MapTy
Implements a partial diagnostic that can be emitted anwyhere in a DiagnosticBuilder stream.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
static VarDecl * buildVarDecl(Sema &S, SourceLocation Loc, QualType Type, IdentifierInfo *II)
Build a variable declaration for move parameter.
static NamedDecl * findAcceptableDecl(Sema &SemaRef, NamedDecl *D, unsigned IDNS)
Retrieve the visible declaration corresponding to D, if any.
static Expr * getOrderedNumberExpr(ArrayRef< OMPClause * > Clauses)
static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack, bool Diagnose=true)
Tries to find omp_depend_t. type.
static Stmt * buildPreInits(ASTContext &Context, MutableArrayRef< Decl * > PreInits)
Build preinits statement for the given declarations.
static void argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, SourceLocation Loc, QualType Ty, SmallVectorImpl< UnresolvedSet< 8 > > &Lookups)
static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, Sema &SemaRef, Decl *D)
static bool checkGenericLoopLastprivate(Sema &S, ArrayRef< OMPClause * > Clauses, OpenMPDirectiveKind K, DSAStackTy *Stack)
static std::pair< ValueDecl *, bool > getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, SourceRange &ERange, bool AllowArraySection=false)
static bool checkSimdlenSafelenSpecified(Sema &S, const ArrayRef< OMPClause * > Clauses)
static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, QualType NewType)
static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, ArrayRef< OMPClause * > Clauses, ArrayRef< OpenMPDirectiveKind > AllowedNameModifiers)
static void handleDeclareVariantConstructTrait(DSAStackTy *Stack, OpenMPDirectiveKind DKind, bool ScopeEntry)
static VarDecl * precomputeExpr(Sema &Actions, SmallVectorImpl< Stmt * > &BodyStmts, Expr *E, StringRef Name)
static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, CXXScopeSpec &MapperIdScopeSpec, const DeclarationNameInfo &MapperId, QualType Type, Expr *UnresolvedMapper)
static bool checkReductionClauseWithNogroup(Sema &S, ArrayRef< OMPClause * > Clauses)
static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, SourceLocation M1Loc, SourceLocation M2Loc)
static void checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, MappableVarListInfo &MVLI, SourceLocation StartLoc, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, ArrayRef< Expr * > UnresolvedMappers, OpenMPMapClauseKind MapType=OMPC_MAP_unknown, ArrayRef< OpenMPMapModifierKind > Modifiers=None, bool IsMapTypeImplicit=false, bool NoDiagnose=false)
static OMPAllocateDeclAttr::AllocatorTypeTy getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator)
static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, bool StrictlyPositive, bool BuildCapture=false, OpenMPDirectiveKind DKind=OMPD_unknown, OpenMPDirectiveKind *CaptureRegion=nullptr, Stmt **HelperValStmt=nullptr)
static Expr * buildPostUpdate(Sema &S, ArrayRef< Expr * > PostUpdates)
Build postupdate expression for the given list of postupdates expressions.
static CapturedStmt * buildLoopVarFunc(Sema &Actions, QualType LoopVarTy, QualType LogicalTy, DeclRefExpr *StartExpr, Expr *Step, bool Deref)
Create a closure that computes the loop variable from the logical iteration number.
static ExprResult buildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, bool IsNonRectangularLB, llvm::MapVector< const Expr *, DeclRefExpr * > *Captures=nullptr)
Build 'VarRef = Start + Iter * Step'.
static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, OpenMPDirectiveKind NameModifier=OMPD_unknown)
static Expr * getCollapseNumberExpr(ArrayRef< OMPClause * > Clauses)
static Expr * getDirectCallExpr(Expr *E)
static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, const Expr *E, QualType BaseQTy)
static OMPCapturedExprDecl * buildCaptureDecl(Sema &S, IdentifierInfo *Id, Expr *CaptureExpr, bool WithInit, DeclContext *CurContext, bool AsExpression)
static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, DSAStackTy *Stack)
Tries to find omp_allocator_handle_t type.
static bool isClauseMappable(ArrayRef< OMPClause * > Clauses)
Check if the variables in the mapping clause are externally visible.
static BinaryOperatorKind getRelatedCompoundReductionOp(BinaryOperatorKind BOK)
static bool checkMutuallyExclusiveClauses(Sema &S, ArrayRef< OMPClause * > Clauses, ArrayRef< OpenMPClauseKind > MutuallyExclusiveClauses)
Find and diagnose mutually exclusive clause kinds.
static bool checkOpenMPIterationSpace(OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, llvm::MutableArrayRef< LoopIterationSpace > ResultIterSpaces, llvm::MapVector< const Expr *, DeclRefExpr * > &Captures)
Called on a for stmt to check and extract its iteration space for further processing (such as collaps...
static bool checkOrderedOrderSpecified(Sema &S, const ArrayRef< OMPClause * > Clauses)
static OpenMPMapClauseKind getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, bool IsAggregateOrDeclareTarget)
static const Expr * getExprAsWritten(const Expr *E)
static bool checkMapConflicts(Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, bool CurrentRegionOnly, OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, OpenMPClauseKind CKind)
static bool isOpenMPDeviceDelayedContext(Sema &S)
static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef)
Convert integer expression E to make it have at least Bits bits.
static std::string getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, ArrayRef< unsigned > Exclude=llvm::None)
static void applyOMPAllocateAttribute(Sema &S, VarDecl *VD, OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator, Expr *Alignment, SourceRange SR)
static bool checkOMPArraySectionConstantForReduction(ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, SmallVectorImpl< llvm::APSInt > &ArraySizes)
static CapturedStmt * buildDistanceFunc(Sema &Actions, QualType LogicalTy, BinaryOperator::Opcode Rel, Expr *StartExpr, Expr *StopExpr, Expr *StepExpr)
Create a closure that computes the number of iterations of a loop.
static bool checkPreviousOMPAllocateAttribute(Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator)
static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, Expr *NumIterations, Sema &SemaRef, Scope *S, DSAStackTy *Stack)
static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, QualType Type, OpenMPClauseKind CKind, SourceLocation ELoc, bool AcceptIfMutable=true, bool ListItemNotVar=false)
static bool isValidInteropVariable(Sema &SemaRef, Expr *InteropVarExpr, SourceLocation VarLoc, OpenMPClauseKind Kind)
static const ValueDecl * getCanonicalDecl(const ValueDecl *D)
static const Expr * checkMapClauseExpressionBase(Sema &SemaRef, Expr *E, OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose)
Return the expression of the base of the mappable expression or null if it cannot be determined and d...
static bool hasClauses(ArrayRef< OMPClause * > Clauses, const OpenMPClauseKind K)
Check for existence of a map clause in the list of clauses.
static void processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy *Stack, SmallVectorImpl< OMPClause * > &Clauses)
Perform DFS through the structure/class data members trying to find member(s) with user-defined 'defa...
static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, OpenMPDirectiveKind CancelRegion, SourceLocation StartLoc)
static DeclRefExpr * buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, SourceLocation Loc, bool RefersToCapture=false)
static ExprResult buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start, bool IsNonRectangularLB, llvm::MapVector< const Expr *, DeclRefExpr * > &Captures)
Build 'VarRef = Start.
static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, Sema &SemaRef, DSAStackTy *Stack, ValueDecl *VD)
static bool findOMPEventHandleT(Sema &S, SourceLocation Loc, DSAStackTy *Stack)
Tries to find omp_event_handle_t type.
static ExprResult buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, Scope *S, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, QualType Ty, CXXCastPath &BasePath, Expr *UnresolvedReduction)
static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef)
Check if the given expression E is a constant integer that fits into Bits bits.
static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, ArrayRef< OMPClause * > Clauses)
static bool actOnOMPReductionKindClause(Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr * > UnresolvedReductions, ReductionData &RD)
static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, const ValueDecl *D, const DSAStackTy::DSAVarData &DVar, bool IsLoopIterVar=false)
static DeclRefExpr * buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, bool WithInit)
static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack)
Tries to find omp_alloctrait_t type.
static bool isConstNotMutableType(Sema &SemaRef, QualType Type, bool AcceptIfMutable=true, bool *IsClassType=nullptr)
static void checkReductionClauses(Sema &S, DSAStackTy *Stack, ArrayRef< OMPClause * > Clauses)
Check consistency of the reduction clauses.
static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, DSAStackTy *Stack, QualType QTy, bool FullCheck=true)
static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, OpenMPDirectiveKind CurrentRegion, const DeclarationNameInfo &CurrentName, OpenMPDirectiveKind CancelRegion, OpenMPBindClauseKind BindKind, SourceLocation StartLoc)
static unsigned checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, DSAStackTy &DSA, Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, OMPLoopBasedDirective::HelperExprs &Built)
Called on a for stmt to check itself and nested loops (if any).
static OpenMPDefaultmapClauseKind getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD)
static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, const Expr *E, QualType BaseQTy)
Return true if it can be proven that the provided array expression (array section or array subscript)...
static T filterLookupForUDReductionAndMapper(SmallVectorImpl< U > &Lookups, const llvm::function_ref< T(ValueDecl *)> Gen)
This file defines OpenMP AST classes for executable directives and clauses.
Expr * getUpdateExpr()
Get helper expression of the form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 'OpaqueValueExp...
Expr * getV()
Get 'v' part of the associated expression/statement.
Expr * getR()
Get 'r' part of the associated expression/statement.
Expr * getD()
Get 'd' part of the associated expression/statement.
Expr * getX()
Get 'x' part of the associated expression/statement.
bool isFailOnly() const
Return true if 'v' is updated only when the condition is evaluated false (compare capture only).
bool isPostfixUpdate() const
Return true if 'v' expression must be updated to original value of 'x', false if 'v' must be updated ...
Expr * getExpr()
Get 'expr' part of the associated expression/statement.
bool isXLHSInRHSPart() const
Return true if helper update expression has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and...
Allows QualTypes to be sorted and hence used in maps and sets.
static OMPCancelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, OpenMPDirectiveKind CancelRegion)
Creates directive.
static OMPCancellationPointDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Creates directive.
static OMPDispatchDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, SourceLocation TargetCallLoc)
Creates directive with a list of Clauses.
static OMPDistributeDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPDistributeParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, bool HasCancel)
Creates directive with a list of Clauses.
static OMPDistributeParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPDistributeSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPGenericLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPInteropDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses)
Creates directive.
static OMPMaskedDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive.
static OMPMaskedTaskLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
static OMPMaskedTaskLoopSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPMasterTaskLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
static OMPMasterTaskLoopSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPParallelGenericLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPParallelMaskedTaskLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
static OMPParallelMaskedTaskLoopSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPParallelMasterTaskLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
static OMPParallelMasterTaskLoopSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPScanDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses)
Creates directive with a list of Clauses.
static OMPTargetDataDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
static OMPTargetDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
static OMPTargetEnterDataDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
static OMPTargetExitDataDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
static OMPTargetParallelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, bool HasCancel)
Creates directive with a list of Clauses.
static OMPTargetParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, bool HasCancel)
Creates directive with a list of Clauses.
static OMPTargetParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPTargetParallelGenericLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPTargetSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPTargetTeamsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
static OMPTargetTeamsDistributeDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPTargetTeamsDistributeParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, bool HasCancel)
Creates directive with a list of Clauses.
static OMPTargetTeamsDistributeParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPTargetTeamsDistributeSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPTargetTeamsGenericLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPTargetUpdateDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
static OMPTaskLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
static OMPTaskLoopSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPTeamsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
static OMPTeamsDistributeDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPTeamsDistributeParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, bool HasCancel)
Creates directive with a list of Clauses.
static OMPTeamsDistributeParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPTeamsDistributeSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPTeamsGenericLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPTileDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, unsigned NumLoops, Stmt *AssociatedStmt, Stmt *TransformedStmt, Stmt *PreInits)
Create a new AST node representation for '#pragma omp tile'.
static OMPUnrollDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, unsigned NumGeneratedLoops, Stmt *TransformedStmt, Stmt *PreInits)
Create a new AST node representation for '#pragma omp unroll'.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
TranslationUnitDecl * getTranslationUnitDecl() const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
QualType getMemberPointerType(QualType T, const Type *Cls) const
Return the uniqued reference to the type for a member pointer to the specified type in the specified ...
DeclarationNameTable DeclarationNames
QualType getUnsignedPointerDiffType() const
Return the unique unsigned counterpart of "ptrdiff_t" integer type.
ASTMutationListener * getASTMutationListener() const
Retrieve a pointer to the AST mutation listener associated with this AST context, if any.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
bool DeclMustBeEmitted(const Decl *D)
Determines if the decl can be CodeGen'ed or deserialized from PCH lazily, only when used; this is onl...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
void Deallocate(void *Ptr) const
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false, bool Unqualified=false, bool AllowCXX=false)
QualType getUIntPtrType() const
Return a type compatible with "uintptr_t" (C99 7.18.1.4), as defined by the target.
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const
getIntTypeForBitwidth - sets integer QualTy according to specified details: bitwidth,...
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
QualType getVariableArrayType(QualType EltTy, Expr *NumElts, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals, SourceRange Brackets) const
Return a non-unique reference to the type for a variable array of the specified element type.
CanQualType BoundMemberTy
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, const Expr *SizeExpr, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
const TargetInfo & getTargetInfo() const
bool typesAreCompatible(QualType T1, QualType T2, bool CompareUnqualified=false)
Compatibility predicates used to check assignment expressions.
An abstract interface that should be implemented by listeners that want to be notified when an AST en...
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
@ AS_Keyword
__ptr16, alignas(...), etc.
Represents an attribute applied to a statement.
static AttributedStmt * Create(const ASTContext &C, SourceLocation Loc, ArrayRef< const Attr * > Attrs, Stmt *SubStmt)
SourceLocation getBeginLoc() const
A builtin binary operation expression such as "x + y" or "x <= y".
static OverloadedOperatorKind getOverloadedOperator(Opcode Opc)
Retrieve the overloaded operator kind that corresponds to the given binary opcode.
static Opcode getOpForCompoundAssignment(Opcode Opc)
bool isRelationalOp() const
SourceLocation getOperatorLoc() const
SourceLocation getExprLoc() const
static Opcode reverseComparisonOp(Opcode Opc)
static Opcode getOverloadedOpcode(OverloadedOperatorKind OO)
Retrieve the binary opcode that corresponds to the given overloaded operator.
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
Represents a C++ constructor within a class.
Represents a C++ conversion function within a class.
A call to an overloaded operator written using operator syntax.
Represents a C++ struct/union/class.
bool hasMutableFields() const
Determine whether this class, or any of its class subobjects, contains a mutable field.
bool hasDefinition() const
Represents a C++ nested-name-specifier or a global scope specifier.
bool isValid() const
A scope specifier is present, and it refers to a real scope.
SourceLocation getBeginLoc() const
bool isSet() const
Deprecated.
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const
Retrieve a nested-name-specifier with location information, copied into the given AST context.
bool isInvalid() const
An error occurred during parsing of the scope specifier.
Represents the this expression in C++.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
static CallExpr * Create(const ASTContext &Ctx, Expr *Fn, ArrayRef< Expr * > Args, QualType Ty, ExprValueKind VK, SourceLocation RParenLoc, FPOptionsOverride FPFeatures, unsigned MinNumArgs=0, ADLCallKind UsesADL=NotADL)
Create a call expression.
SourceLocation getBeginLoc() const LLVM_READONLY
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
QualType withConst() const
Retrieves a version of this type with const applied.
A wrapper class around a pointer that always points to its canonical declaration.
Represents the body of a CapturedStmt, and serves as its DeclContext.
unsigned getNumParams() const
void setNothrow(bool Nothrow=true)
ImplicitParamDecl * getParam(unsigned i) const
Describes the capture of either a variable, or 'this', or variable-length array type.
This captures a statement into a function.
CapturedDecl * getCapturedDecl()
Retrieve the outlined function declaration.
SourceRange getSourceRange() const LLVM_READONLY
Stmt * getCapturedStmt()
Retrieve the statement being captured.
bool capturesVariable(const VarDecl *Var) const
True if this variable has been captured.
SourceLocation getBeginLoc() const LLVM_READONLY
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Declaration of a class template.
Complex values, per C99 6.2.5p11.
CompoundStmt - This represents a group of statements like { stmt stmt }.
SourceLocation getBeginLoc() const
static CompoundStmt * Create(const ASTContext &C, ArrayRef< Stmt * > Stmts, FPOptionsOverride FPFeatures, SourceLocation LB, SourceLocation RB)
ConditionalOperator - The ?: ternary operator.
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)
The results of name lookup within a DeclContext.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC.
bool isFileContext() const
bool isExternCXXContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
bool isTranslationUnit() const
void addDecl(Decl *D)
Add the declaration D into this context.
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
bool isExternCContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
bool Encloses(const DeclContext *DC) const
Determine whether this declaration context encloses the declaration context DC.
void addHiddenDecl(Decl *D)
Add the declaration D to this context without modifying any lookup tables.
static DeclGroupRef Create(ASTContext &C, Decl **Decls, unsigned NumDecls)
A reference to a declared variable, function, enum, etc.
SourceLocation getBeginLoc() const LLVM_READONLY
static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr, NonOdrUseReason NOUR=NOUR_None)
SourceLocation getEndLoc() const LLVM_READONLY
ConstexprSpecKind getConstexprSpecifier() const
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
const Decl * getSingleDecl() const
Decl - This represents one declaration (or definition), e.g.
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
void markUsed(ASTContext &C)
Mark the declaration used, in the sense of odr-use.
bool isReferenced() const
Whether any declaration of this entity was referenced.
bool isCanonicalDecl() const
Whether this particular Decl is a canonical one.
bool isInvalidDecl() const
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
void setAccess(AccessSpecifier AS)
SourceLocation getLocation() const
void setImplicit(bool I=true)
void setReferenced(bool R=true)
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required.
DeclContext * getDeclContext()
AccessSpecifier getAccess() const
void setDeclContext(DeclContext *DC)
setDeclContext - Set both the semantic and lexical DeclContext to DC.
void setLexicalDeclContext(DeclContext *DC)
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
The name of a declaration.
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
OverloadedOperatorKind getCXXOverloadedOperator() const
If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...
bool isEmpty() const
Evaluates true when this declaration name is empty.
Information about one declarator, including the parsed type information and the identifier.
void SetIdentifier(IdentifierInfo *Id, SourceLocation IdLoc)
Set the name of this declarator to be the given identifier.
const DeclSpec & getDeclSpec() const
getDeclSpec - Return the declaration-specifier that this declarator was declared with.
SourceLocation getIdentifierLoc() const
SourceLocation getBeginLoc() const LLVM_READONLY
void setFunctionDefinitionKind(FunctionDefinitionKind Val)
const CXXScopeSpec & getCXXScopeSpec() const
getCXXScopeSpec - Return the C++ scope specifier (global scope or nested-name-specifier) that is part...
IdentifierInfo * getIdentifier() const
bool isInvalidType() const
RAII object that enters a new expression evaluation context.
The return type of classify().
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
@ SE_AllowSideEffects
Allow any unmodeled side effect.
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
bool isValueDependent() const
Determines whether the value of this expression depends on.
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
bool isTypeDependent() const
Determines whether the type of this expression depends on.
bool containsUnexpandedParameterPack() const
Whether this expression contains an unexpanded parameter pack (for C++11 variadic templates).
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Expr * IgnoreParenLValueCasts() LLVM_READONLY
Skip past any parentheses and lvalue casts which might surround this expression until reaching a fixe...
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
bool containsErrors() const
Whether this expression contains subexpressions which had errors, e.g.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
bool isIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr, bool isEvaluated=true) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
Represents difference between two FPOptions values.
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
FieldDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this field.
static FloatingLiteral * Create(const ASTContext &C, const llvm::APFloat &V, bool isexact, QualType Type, SourceLocation L)
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
ArrayRef< ParmVarDecl * > parameters() const
bool isConstexpr() const
Whether this is a (C++11) constexpr function or constexpr constructor.
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Represents a prototype with parameter type info, e.g.
One of these records is kept for each identifier that is lexed.
void setMangledOpenMPVariantName(bool I)
Set whether this is the mangled name of an OpenMP variant.
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
IfStmt - This represents an if/then/else.
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1....
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat, FPOptionsOverride FPO)
ImplicitConversionSequence - Represents an implicit conversion sequence, which may be a standard conv...
Describes the kind of initialization being performed, along with location information for tokens rela...
static InitializationKind CreateCopy(SourceLocation InitLoc, SourceLocation EqualLoc, bool AllowExplicitConvs=false)
Create a copy initialization.
Describes the sequence of initializations required to initialize a given object or reference with a s...
ExprResult Perform(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, MultiExprArg Args, QualType *ResultType=nullptr)
Perform the actual initialization of the given entity based on the computed initialization sequence.
Describes an entity that is being initialized.
static InitializedEntity InitializeVariable(VarDecl *Var)
Create the initialization entity for a variable.
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
Describes the capture of a variable or of this, or of a C++1y init-capture.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
A class for iterating through a result set and possibly filtering out results.
Represents the results of name lookup.
LLVM_ATTRIBUTE_REINITIALIZES void clear()
Clears out any current state.
DeclClass * getAsSingle() const
bool empty() const
Return true if no decls were found.
Filter makeFilter()
Create a filter for this result set.
NamedDecl * getFoundDecl() const
Fetch the unique decl found by this lookup.
bool isSingleResult() const
Determines if this names a single result which is not an unresolved value using decl.
NamedDecl * getRepresentativeDecl() const
Fetches a representative decl. Useful for lazy diagnostics.
void suppressDiagnostics()
Suppress the diagnostics that would normally fire because of this lookup.
static bool isVisible(Sema &SemaRef, NamedDecl *D)
Determine whether the given declaration is visible to the program.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
static MemberExpr * CreateImplicit(const ASTContext &C, Expr *Base, bool IsArrow, ValueDecl *MemberDecl, QualType T, ExprValueKind VK, ExprObjectKind OK)
Create an implicit MemberExpr, with no location, qualifier, template arguments, and so on.
SourceLocation getExprLoc() const LLVM_READONLY
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
virtual void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const
Appends a human-readable name for this declaration into the given stream.
A C++ nested-name-specifier augmented with source location information.
This represents 'acq_rel' clause in the '#pragma omp atomic|flush' directives.
This represents 'acquire' clause in the '#pragma omp atomic|flush' directives.
static OMPAffinityClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, Expr *Modifier, ArrayRef< Expr * > Locators)
Creates clause with a modifier a list of locator items.
static OMPAlignClause * Create(const ASTContext &C, Expr *A, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build 'align' clause with the given alignment.
static OMPAlignedClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, Expr *A)
Creates clause with a list of variables VL and alignment A.
static OMPAllocateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, Expr *Allocator, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
static bool classof(const OMPClause *T)
static OMPAllocateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef< Expr * > VL, ArrayRef< OMPClause * > CL)
This represents 'allocator' clause in the '#pragma omp ...' directive.
OpenMP 5.0 [2.1.5, Array Sections].
Expr * getLength()
Get length of array section.
SourceLocation getColonLocFirst() const
Expr * getBase()
An array section can be written only as Base[LowerBound:Length].
static QualType getBaseOriginalType(const Expr *Base)
Return original type of the base expression for array section.
Expr * getLowerBound()
Get lower bound of array section.
An explicit cast in C or a C-style cast in C++, which uses the syntax ([s1][s2]......
Expr * getBase()
Fetches base expression of array shaping expression.
This represents 'atomic_default_mem_order' clause in the '#pragma omp requires' directive.
This represents 'bind' clause in the '#pragma omp ...' directives.
static OMPBindClause * Create(const ASTContext &C, OpenMPBindClauseKind K, SourceLocation KLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build 'bind' clause with kind K ('teams', 'parallel', or 'thread').
This represents 'capture' clause in the '#pragma omp atomic' directive.
Pseudo declaration for capturing expressions.
static OMPCapturedExprDecl * Create(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, QualType T, SourceLocation StartLoc)
Class that represents a component of a mappable expression.
ValueDecl * getAssociatedDeclaration() const
static OMPClauseWithPostUpdate * get(OMPClause *C)
Class that handles pre-initialization statement for some clauses, like 'shedule', 'firstprivate' etc.
static OMPClauseWithPreInit * get(OMPClause *C)
This is a basic class for representing single OpenMP clause.
SourceLocation getBeginLoc() const
Returns the starting location of the clause.
SourceLocation getEndLoc() const
Returns the ending location of the clause.
OpenMPClauseKind getClauseKind() const
Returns kind of OpenMP clause (private, shared, reduction, etc.).
This represents 'collapse' clause in the '#pragma omp ...' directive.
This represents 'compare' clause in the '#pragma omp atomic' directive.
static OMPCopyinClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > SrcExprs, ArrayRef< Expr * > DstExprs, ArrayRef< Expr * > AssignmentOps)
Creates clause with a list of variables VL.
static OMPCopyprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > SrcExprs, ArrayRef< Expr * > DstExprs, ArrayRef< Expr * > AssignmentOps)
Creates clause with a list of variables VL.
This represents '#pragma omp declare mapper ...' directive.
static OMPDeclareMapperDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, QualType T, DeclarationName VarName, ArrayRef< OMPClause * > Clauses, OMPDeclareMapperDecl *PrevDeclInScope)
Creates declare mapper node.
This represents '#pragma omp declare reduction ...' directive.
static OMPDeclareReductionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, QualType T, OMPDeclareReductionDecl *PrevDeclInScope)
Create declare reduction node.
This represents 'default' clause in the '#pragma omp ...' directive.
This represents 'defaultmap' clause in the '#pragma omp ...' directive.
This represents implicit clause 'depend' for the '#pragma omp task' directive.
static OMPDependClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, DependDataTy Data, Expr *DepModifier, ArrayRef< Expr * > VL, unsigned NumLoops)
Creates clause with a list of variables VL.
static OMPDepobjClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, Expr *Depobj)
Creates clause.
This represents 'destroy' clause in the '#pragma omp depobj' directive or the '#pragma omp interop' d...
This represents 'detach' clause in the '#pragma omp task' directive.
This represents 'device' clause in the '#pragma omp ...' directive.
This represents 'dist_schedule' clause in the '#pragma omp ...' directive.
This represents 'dynamic_allocators' clause in the '#pragma omp requires' directive.
static OMPExclusiveClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
This represents 'filter' clause in the '#pragma omp ...' directive.
This represents 'final' clause in the '#pragma omp ...' directive.
static OMPFirstprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > PrivateVL, ArrayRef< Expr * > InitVL, Stmt *PreInit)
Creates clause with a list of variables VL.
This represents implicit clause 'flush' for the '#pragma omp flush' directive.
static OMPFlushClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
static OMPFromClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists, ArrayRef< Expr * > UDMapperRefs, ArrayRef< OpenMPMotionModifierKind > MotionModifiers, ArrayRef< SourceLocation > MotionModifiersLoc, NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId)
Creates clause with a list of variables Vars.
Representation of the 'full' clause of the '#pragma omp unroll' directive.
static OMPFullClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Build an AST node for a 'full' clause.
This represents 'grainsize' clause in the '#pragma omp ...' directive.
static OMPHasDeviceAddrClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
This represents 'hint' clause in the '#pragma omp ...' directive.
This represents 'if' clause in the '#pragma omp ...' directive.
static OMPInReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef< Expr * > Privates, ArrayRef< Expr * > LHSExprs, ArrayRef< Expr * > RHSExprs, ArrayRef< Expr * > ReductionOps, ArrayRef< Expr * > TaskgroupDescriptors, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
static OMPInclusiveClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
static OMPInitClause * Create(const ASTContext &C, Expr *InteropVar, ArrayRef< Expr * > PrefExprs, bool IsTarget, bool IsTargetSync, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)
Creates a fully specified clause.
static OMPIsDevicePtrClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
static OMPLastprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > SrcExprs, ArrayRef< Expr * > DstExprs, ArrayRef< Expr * > AssignmentOps, OpenMPLastprivateModifier LPKind, SourceLocation LPKindLoc, SourceLocation ColonLoc, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
This represents clause 'linear' in the '#pragma omp ...' directives.
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > PL, ArrayRef< Expr * > IL, Expr *Step, Expr *CalcStep, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.
static OMPMapClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists, ArrayRef< Expr * > UDMapperRefs, ArrayRef< OpenMPMapModifierKind > MapModifiers, ArrayRef< SourceLocation > MapModifiersLoc, NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId, OpenMPMapClauseKind Type, bool TypeIsImplicit, SourceLocation TypeLoc)
Creates clause with a list of variables VL.
This represents 'mergeable' clause in the '#pragma omp ...' directive.
This represents 'nocontext' clause in the '#pragma omp ...' directive.
This represents 'nogroup' clause in the '#pragma omp ...' directive.
static OMPNontemporalClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
This represents 'novariants' clause in the '#pragma omp ...' directive.
This represents 'nowait' clause in the '#pragma omp ...' directive.
This represents 'num_tasks' clause in the '#pragma omp ...' directive.
This represents 'num_teams' clause in the '#pragma omp ...' directive.
This represents 'num_threads' clause in the '#pragma omp ...' directive.
This represents 'order' clause in the '#pragma omp ...' directive.
SourceLocation getKindKwLoc() const
Returns location of clause kind.
OpenMPOrderClauseKind getKind() const
Returns kind of the clause.
This represents 'ordered' clause in the '#pragma omp ...' directive.
Expr * getNumForLoops() const
Return the number of associated for-loops.
static OMPOrderedClause * Create(const ASTContext &C, Expr *Num, unsigned NumLoops, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build 'ordered' clause.
Representation of the 'partial' clause of the '#pragma omp unroll' directive.
static OMPPartialClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, Expr *Factor)
Build an AST node for a 'partial' clause.
Expr * getFactor() const
Returns the argument of the clause or nullptr if not set.
This represents 'priority' clause in the '#pragma omp ...' directive.
static OMPPrivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > PrivateVL)
Creates clause with a list of variables VL.
This represents 'proc_bind' clause in the '#pragma omp ...' directive.
This represents 'read' clause in the '#pragma omp atomic' directive.
static OMPReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, OpenMPReductionClauseModifier Modifier, ArrayRef< Expr * > VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef< Expr * > Privates, ArrayRef< Expr * > LHSExprs, ArrayRef< Expr * > RHSExprs, ArrayRef< Expr * > ReductionOps, ArrayRef< Expr * > CopyOps, ArrayRef< Expr * > CopyArrayTemps, ArrayRef< Expr * > CopyArrayElems, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
This represents 'relaxed' clause in the '#pragma omp atomic' directives.
This represents 'release' clause in the '#pragma omp atomic|flush' directives.
This represents '#pragma omp requires...' directive.
clauselist_range clauselists()
static OMPRequiresDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef< OMPClause * > CL)
Create requires node.
This represents 'reverse_offload' clause in the '#pragma omp requires' directive.
This represents 'simd' clause in the '#pragma omp ...' directive.
This represents 'safelen' clause in the '#pragma omp ...' directive.
Expr * getSafelen() const
Return safe iteration space distance.
This represents 'schedule' clause in the '#pragma omp ...' directive.
SourceLocation getFirstScheduleModifierLoc() const
Get the first modifier location.
OpenMPScheduleClauseModifier getSecondScheduleModifier() const
Get the second modifier of the clause.
OpenMPScheduleClauseModifier getFirstScheduleModifier() const
Get the first modifier of the clause.
SourceLocation getSecondScheduleModifierLoc() const
Get the second modifier location.
This represents 'seq_cst' clause in the '#pragma omp atomic' directive.
static OMPSharedClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
This represents 'simdlen' clause in the '#pragma omp ...' directive.
Expr * getSimdlen() const
Return safe iteration space distance.
This represents the 'sizes' clause in the '#pragma omp tile' directive.
static OMPSizesClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > Sizes)
Build a 'sizes' AST node.
unsigned getNumSizes() const
Returns the number of list items.
MutableArrayRef< Expr * > getSizesRefs()
Returns the tile size expressions.
static OMPTaskReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef< Expr * > Privates, ArrayRef< Expr * > LHSExprs, ArrayRef< Expr * > RHSExprs, ArrayRef< Expr * > ReductionOps, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
This represents 'thread_limit' clause in the '#pragma omp ...' directive.
This represents '#pragma omp threadprivate ...' directive.
static OMPThreadPrivateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef< Expr * > VL)
This represents 'threads' clause in the '#pragma omp ...' directive.
static OMPToClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists, ArrayRef< Expr * > UDMapperRefs, ArrayRef< OpenMPMotionModifierKind > MotionModifiers, ArrayRef< SourceLocation > MotionModifiersLoc, NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId)
Creates clause with a list of variables Vars.
Helper data structure representing the traits in a match clause of an declare variant or metadirectiv...
bool isExtensionActive(llvm::omp::TraitProperty TP)
Check the extension trait TP is active.
bool anyScoreOrCondition(llvm::function_ref< bool(Expr *&, bool)> Cond)
void getAsVariantMatchInfo(ASTContext &ASTCtx, llvm::omp::VariantMatchInfo &VMI) const
Create a variant match info object from this trait info object.
This represents 'unified_address' clause in the '#pragma omp requires' directive.
This represents 'unified_shared_memory' clause in the '#pragma omp requires' directive.
This represents 'untied' clause in the '#pragma omp ...' directive.
static OMPUpdateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates clause for 'atomic' directive.
This represents the 'use' clause in '#pragma omp ...' directives.
static OMPUseDeviceAddrClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
static OMPUseDevicePtrClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr * > Vars, ArrayRef< Expr * > PrivateVars, ArrayRef< Expr * > Inits, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
static OMPUsesAllocatorsClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< OMPUsesAllocatorsClause::Data > Data)
Creates clause with a list of allocators Data.
SourceLocation getLParenLoc() const
Returns the location of '('.
This represents 'write' clause in the '#pragma omp atomic' directive.
Wrapper for void* pointer.
void * getAsOpaquePtr() const
static OpaquePtr make(PtrTy P)
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Represents a parameter to a function.
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
IdentifierTable & getIdentifierTable()
static PseudoObjectExpr * Create(const ASTContext &Context, Expr *syntactic, ArrayRef< Expr * > semantic, unsigned resultIndex)
A (possibly-)qualified type.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
bool hasQualifiers() const
Determine whether this type has any qualifiers.
QualType withRestrict() const
QualType getNonLValueExprType(const ASTContext &Context) const
Determine the type of a (typically non-lvalue) expression with the specified result type.
QualType withConst() const
void addConst()
Add the const type qualifier to this QualType.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
bool isConstant(const ASTContext &Ctx) const
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
bool isMoreQualifiedThan(QualType Other) const
Determine whether this type is more qualified than the other given type, requiring exact equality for...
const Type * getTypePtrOrNull() const
Represents a struct/union/class.
field_range fields() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
decl_type * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
decl_type * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
Base for LValueReferenceType and RValueReferenceType.
Scope - A scope is a transient data structure that is used while parsing the program.
bool isDeclScope(const Decl *D) const
isDeclScope - Return true if this is the scope that the specified decl is declared in.
Scope * getBreakParent()
getBreakParent - Return the closest scope that a break statement would be affected by.
const Scope * getParent() const
getParent - Return the scope that this is nested in.
bool isOpenMPLoopScope() const
Determine whether this scope is a loop having OpenMP loop directive attached.
A RAII object to enter scope of a compound statement.
A generic diagnostic builder for errors which may or may not be deferred.
RAII class used to indicate that we are performing provisional semantic analysis to determine the val...
Abstract base class used for diagnosing integer constant expression violations.
Sema - This implements semantic analysis and AST building for C.
ExprResult PerformImplicitConversion(Expr *From, QualType ToType, AssignmentAction Action, bool AllowExplicit=false)
PerformImplicitConversion - Perform an implicit conversion of the expression From to the type ToType.
ParsedType CreateParsedType(QualType T, TypeSourceInfo *TInfo)
Package the given type and TSI into a ParsedType.
OMPClause * ActOnOpenMPDependClause(const OMPDependClause::DependDataTy &Data, Expr *DepModifier, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'depend' clause.
QualType getCurrentThisType()
Try to retrieve the type of the 'this' pointer.
Scope * getCurScope() const
Retrieve the parser's current scope.
const ValueDecl * getOpenMPDeclareMapperVarName() const
OMPClause * ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'unified_address' clause.
DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveStart(Scope *S, DeclContext *DC, DeclarationName Name, ArrayRef< std::pair< QualType, SourceLocation > > ReductionTypes, AccessSpecifier AS, Decl *PrevDeclInScope=nullptr)
Called on start of '#pragma omp declare reduction'.
DeclGroupPtrTy ActOnOpenMPDeclareSimdDirective(DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, ArrayRef< Expr * > Uniforms, ArrayRef< Expr * > Aligneds, ArrayRef< Expr * > Alignments, ArrayRef< Expr * > Linears, ArrayRef< unsigned > LinModifiers, ArrayRef< Expr * > Steps, SourceRange SR)
Called on well-formed '#pragma omp declare simd' after parsing of the associated method/function.
bool isDeclInScope(NamedDecl *D, DeclContext *Ctx, Scope *S=nullptr, bool AllowInlineNamespace=false)
isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true if 'D' is in Scope 'S',...
SemaDiagnosticBuilder diagIfOpenMPHostCode(SourceLocation Loc, unsigned DiagID, FunctionDecl *FD)
Creates a SemaDiagnosticBuilder that emits the diagnostic if the current context is "used as host cod...
OMPClause * ActOnOpenMPNumThreadsClause(Expr *NumThreads, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_threads' clause.
ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val)
void BuildBasePathArray(const CXXBasePaths &Paths, CXXCastPath &BasePath)
ExprResult IgnoredValueConversions(Expr *E)
IgnoredValueConversions - Given that an expression's result is syntactically ignored,...
OMPClause * ActOnOpenMPNovariantsClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'novariants' clause.
StmtResult ActOnOpenMPTargetTeamsDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target teams' after parsing of the associated statement.
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
@ LookupOMPReductionName
Look up the name of an OpenMP user-defined reduction operation.
@ LookupOMPMapperName
Look up the name of an OpenMP user-defined mapper.
@ LookupAnyName
Look up any declaration with any name.
OMPClause * ActOnOpenMPWriteClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'write' clause.
OMPClause * ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind, ArrayRef< unsigned > Arguments, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, ArrayRef< SourceLocation > ArgumentsLoc, SourceLocation DelimLoc, SourceLocation EndLoc)
OMPClause * ActOnOpenMPExclusiveClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'exclusive' clause.
static int getOpenMPCaptureLevels(OpenMPDirectiveKind Kind)
Return the number of captured regions created for an OpenMP directive.
OMPClause * ActOnOpenMPUseDevicePtrClause(ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs)
Called on well-formed 'use_device_ptr' clause.
ImplicitConversionSequence TryImplicitConversion(Expr *From, QualType ToType, bool SuppressUserConversions, AllowedExplicit AllowExplicit, bool InOverloadResolution, bool CStyle, bool AllowObjCWritebackConversion)
StmtResult ActOnOpenMPScanDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp scan'.
OMPClause * ActOnOpenMPGrainsizeClause(Expr *Size, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'grainsize' clause.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
void ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init)
Check if the current region is an OpenMP loop region and if it is, mark loop control variable,...
std::pair< StringRef, QualType > CapturedParamNameType
OMPClause * ActOnOpenMPToClause(ArrayRef< OpenMPMotionModifierKind > MotionModifiers, ArrayRef< SourceLocation > MotionModifiersLoc, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs, ArrayRef< Expr * > UnresolvedMappers=llvm::None)
Called on well-formed 'to' clause.
void ActOnOpenMPEndAssumesDirective()
Called on well-formed '#pragma omp end assumes'.
OMPClause * ActOnOpenMPFlushClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'flush' pseudo clause.
void DiagnoseUnterminatedOpenMPDeclareTarget()
Report unterminated 'omp declare target' or 'omp begin declare target' at the end of a compilation un...
OMPClause * ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier, Expr *Device, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation EndLoc)
Called on well-formed 'device' clause.
OMPClause * ActOnOpenMPUseDeviceAddrClause(ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs)
Called on well-formed 'use_device_addr' clause.
OMPClause * ActOnOpenMPPriorityClause(Expr *Priority, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'priority' clause.
FunctionEmissionStatus
Status of the function emission on the CUDA/HIP/OpenMP host/device attrs.
StmtResult ActOnOpenMPOrderedDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp ordered' after parsing of the associated statement.
OMPClause * ActOnOpenMPLinearClause(ArrayRef< Expr * > VarList, Expr *Step, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'linear' clause.
void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl=nullptr, ExpressionEvaluationContextRecord::ExpressionKind Type=ExpressionEvaluationContextRecord::EK_Other)
StmtResult ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Called on well-formed '#pragma omp cancellation point'.
ExprResult CheckBooleanCondition(SourceLocation Loc, Expr *E, bool IsConstexpr=false)
CheckBooleanCondition - Diagnose problems involving the use of the given expression as a boolean cond...
OMPClause * ActOnOpenMPNowaitClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'nowait' clause.
bool isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const
OMPClause * ActOnOpenMPClause(OpenMPClauseKind Kind, SourceLocation StartLoc, SourceLocation EndLoc)
SmallVector< sema::FunctionScopeInfo *, 4 > FunctionScopes
Stack containing information about each of the nested function, block, and method scopes that are cur...
StmtResult ActOnOpenMPDistributeParallelForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute parallel for' after parsing of the associated statement...
PoppedFunctionScopePtr PopFunctionScopeInfo(const sema::AnalysisBasedWarnings::Policy *WP=nullptr, const Decl *D=nullptr, QualType BlockType=QualType())
Pop a function (or block or lambda or captured region) scope from the stack.
OMPClause * ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'dynamic_allocators' clause.
OMPClause * ActOnOpenMPAllocateClause(Expr *Allocator, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'allocate' clause.
StmtResult ActOnOpenMPTargetSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target simd' after parsing of the associated statement.
StmtResult ActOnOpenMPForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp for' after parsing of the associated statement.
NamedDecl * HandleDeclarator(Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParameterLists)
ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, VerifyICEDiagnoser &Diagnoser, AllowFoldKind CanFold=NoFold)
VerifyIntegerConstantExpression - Verifies that an expression is an ICE, and reports the appropriate ...
StmtResult ActOnOpenMPLoopnest(Stmt *AStmt)
Process a canonical OpenMP loop nest that can either be a canonical literal loop (ForStmt or CXXForRa...
OMPClause * ActOnOpenMPSIMDClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'simd' clause.
StmtResult ActOnOpenMPTargetParallelForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target parallel for' after parsing of the associated statement.
FPOptionsOverride CurFPFeatureOverrides()
ExprResult ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType, SourceLocation StartLoc, DeclarationName VN)
Build the mapper variable of '#pragma omp declare mapper'.
StmtResult ActOnOpenMPTaskwaitDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskwait'.
TypeResult ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D)
Check variable declaration in 'omp declare mapper' construct.
StmtResult ActOnOpenMPDistributeParallelForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute parallel for simd' after parsing of the associated stat...
DeclGroupPtrTy ActOnOpenMPRequiresDirective(SourceLocation Loc, ArrayRef< OMPClause * > ClauseList)
Called on well-formed '#pragma omp requires'.
void MarkDeclarationsReferencedInExpr(Expr *E, bool SkipLocalVariables=false, ArrayRef< const Expr * > StopAt=None)
Mark any declarations that appear within this expression or any potentially-evaluated subexpressions ...
ParsedType getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec *SS=nullptr, bool isClassName=false, bool HasTrailingDot=false, ParsedType ObjectType=nullptr, bool IsCtorOrDtorName=false, bool WantNontrivialTypeSourceInfo=false, bool IsClassTemplateDeductionContext=true, IdentifierInfo **CorrectedII=nullptr)
If the identifier refers to a type name within this scope, return the declaration of that type.
void startOpenMPLoop()
If the current region is a loop-based region, mark the start of the loop construct.
OMPClause * ActOnOpenMPDestroyClause(Expr *InteropVar, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)
Called on well-formed 'destroy' clause.
ExprResult PerformContextualImplicitConversion(SourceLocation Loc, Expr *FromE, ContextualImplicitConverter &Converter)
Perform a contextual implicit conversion.
OMPClause * ActOnOpenMPBindClause(OpenMPBindClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on a well-formed 'bind' clause.
bool isInOpenMPTaskUntiedContext() const
Return true if currently in OpenMP task with untied clause context.
StmtResult ActOnOpenMPMaskedTaskLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp masked taskloop' after parsing of the associated statement.
StmtResult ActOnOpenMPTargetExitDataDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AStmt)
Called on well-formed '#pragma omp target exit data' after parsing of the associated statement.
OMPClause * ActOnOpenMPFinalClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'final' clause.
OMPClause * ActOnOpenMPMapClause(ArrayRef< OpenMPMapModifierKind > MapTypeModifiers, ArrayRef< SourceLocation > MapTypeModifiersLoc, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs, bool NoDiagnose=false, ArrayRef< Expr * > UnresolvedMappers=llvm::None)
Called on well-formed 'map' clause.
void ActOnCapturedRegionError()
StmtResult ActOnOpenMPFlushDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp flush'.
OMPClause * ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef< Expr * > Vars, const OMPVarListLocTy &Locs, OpenMPVarListDataTy &Data)
OMPClause * ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'hint' clause.
OMPClause * ActOnOpenMPSimpleClause(OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
DeclGroupPtrTy ActOnOpenMPThreadprivateDirective(SourceLocation Loc, ArrayRef< Expr * > VarList)
Called on well-formed '#pragma omp threadprivate'.
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)
void PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext=true)
Add this decl to the scope shadowed decl chains.
ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)
ASTContext & getASTContext() const
void finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller, const FunctionDecl *Callee, SourceLocation Loc)
Finishes analysis of the deferred functions calls that may be declared as host/nohost during device/h...
StmtResult ActOnOpenMPDistributeSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute simd' after parsing of the associated statement.
OMPClause * ActOnOpenMPSharedClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'shared' clause.
NamedDecl * LookupSingleName(Scope *S, DeclarationName Name, SourceLocation Loc, LookupNameKind NameKind, RedeclarationKind Redecl=NotForRedeclaration)
Look up a name, looking for a single declaration.
StmtResult ActOnOpenMPTargetUpdateDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AStmt)
Called on well-formed '#pragma omp target update'.
OMPClause * ActOnOpenMPInitClause(Expr *InteropVar, ArrayRef< Expr * > PrefExprs, bool IsTarget, bool IsTargetSync, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)
Called on well-formed 'init' clause.
StmtResult ActOnOpenMPSingleDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp single' after parsing of the associated statement.
StmtResult ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams distribute parallel for simd' after parsing of the as...
OMPClause * ActOnOpenMPCaptureClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'capture' clause.
void PopExpressionEvaluationContext()
StmtResult ActOnOpenMPRegionEnd(StmtResult S, ArrayRef< OMPClause * > Clauses)
End of OpenMP region.
StmtResult ActOnOpenMPParallelMaskedTaskLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel masked taskloop' after parsing of the associated statemen...
SemaDiagnosticBuilder diagIfOpenMPDeviceCode(SourceLocation Loc, unsigned DiagID, FunctionDecl *FD)
Creates a SemaDiagnosticBuilder that emits the diagnostic if the current context is "used as device c...
StmtResult ActOnOpenMPTargetParallelDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target parallel' after parsing of the associated statement.
@ None
This is not a defaultable comparison operator.
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
bool isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level, unsigned CaptureLevel) const
Check if the specified global variable must be captured by outer capture regions.
DeclRefExpr * BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, SourceLocation Loc, const CXXScopeSpec *SS=nullptr)
StmtResult ActOnOpenMPParallelMasterDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp parallel master' after parsing of the associated statement.
StmtResult ActOnOpenMPTargetDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target' after parsing of the associated statement.
StmtResult ActOnOpenMPCancelDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Called on well-formed '#pragma omp cancel'.
OMPClause * ActOnOpenMPUntiedClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'untied' clause.
void FindAssociatedClassesAndNamespaces(SourceLocation InstantiationLoc, ArrayRef< Expr * > Args, AssociatedNamespaceSet &AssociatedNamespaces, AssociatedClassSet &AssociatedClasses)
Find the associated classes and namespaces for argument-dependent lookup for a call with the given se...
ExprResult ActOnOpenMPIdExpression(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id, OpenMPDirectiveKind Kind)
Called on correct id-expression from the '#pragma omp threadprivate'.
OMPClause * ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
void checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, SourceLocation IdLoc=SourceLocation())
Check declaration inside target region.
OMPClause * ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'update' clause.
ExprResult PerformOpenMPImplicitIntegerConversion(SourceLocation OpLoc, Expr *Op)
void PushFunctionScope()
Enter a new function scope.
OMPClause * ActOnOpenMPFirstprivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'firstprivate' clause.
void tryCaptureOpenMPLambdas(ValueDecl *V)
Function tries to capture lambda's captured variables in the OpenMP region before the original lambda...
StmtResult ActOnOpenMPDepobjDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp depobj'.
StmtResult ActOnOpenMPInteropDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp interop'.
const LangOptions & getLangOpts() const
TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, Sema::LookupNameKind LookupKind, Scope *S, CXXScopeSpec *SS, CorrectionCandidateCallback &CCC, CorrectTypoKind Mode, DeclContext *MemberContext=nullptr, bool EnteringContext=false, const ObjCObjectPointerType *OPT=nullptr, bool RecordFailure=true)
Try to "correct" a typo in the source code by finding visible declarations whose names are similar to...
OMPClause * ActOnOpenMPAcquireClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'acquire' clause.
void ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D)
Initialize declare reduction construct initializer.
OMPClause * ActOnOpenMPScheduleClause(OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Called on well-formed 'schedule' clause.
OMPClause * ActOnOpenMPHasDeviceAddrClause(ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs)
Called on well-formed 'has_device_addr' clause.
ExprResult BuildCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr, bool IsExecConfig=false, bool AllowRecovery=false)
BuildCallExpr - Handle a call to Fn with the specified array of arguments.
AccessResult CheckBaseClassAccess(SourceLocation AccessLoc, QualType Base, QualType Derived, const CXXBasePath &Path, unsigned DiagID, bool ForceCheck=false, bool ForceUnprivileged=false)
Checks access for a hierarchy conversion.
OMPClause * ActOnOpenMPAcqRelClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'acq_rel' clause.
StmtResult ActOnOpenMPParallelMasterTaskLoopSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel master taskloop simd' after parsing of the associated sta...
void ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(Decl *D, SmallVectorImpl< FunctionDecl * > &Bases)
Register D as specialization of all base functions in Bases in the current omp begin/end declare vari...
DeclGroupPtrTy ActOnOpenMPAllocateDirective(SourceLocation Loc, ArrayRef< Expr * > VarList, ArrayRef< OMPClause * > Clauses, DeclContext *Owner=nullptr)
Called on well-formed '#pragma omp allocate'.
void CheckExtraCXXDefaultArguments(Declarator &D)
CheckExtraCXXDefaultArguments - Check for any extra default arguments in the declarator,...
OMPClause * ActOnOpenMPSimdlenClause(Expr *Length, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'simdlen' clause.
const LangOptions & LangOpts
sema::LambdaScopeInfo * getCurLambda(bool IgnoreNonLambdaCapturingScope=false)
Retrieve the current lambda scope info, if any.
OMPClause * ActOnOpenMPFilterClause(Expr *ThreadID, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'filter' clause.
OMPClause * ActOnOpenMPAffinityClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, Expr *Modifier, ArrayRef< Expr * > Locators)
Called on well-formed 'affinity' clause.
OMPClause * ActOnOpenMPProcBindClause(llvm::omp::ProcBindKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'proc_bind' clause.
OMPThreadPrivateDecl * CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef< Expr * > VarList)
Builds a new OpenMPThreadPrivateDecl and checks its correctness.
void startOpenMPCXXRangeFor()
If the current region is a range loop-based region, mark the start of the loop construct.
void setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, unsigned Level)
Sets OpenMP capture kind (OMPC_private, OMPC_firstprivate, OMPC_map etc.) for FD based on DSA for the...
OMPClause * ActOnOpenMPSeqCstClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'seq_cst' clause.
StmtResult ActOnOpenMPMaskedTaskLoopSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp masked taskloop simd' after parsing of the associated statement.
OMPClause * ActOnOpenMPAlignClause(Expr *Alignment, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'align' clause.
StmtResult ActOnOpenMPForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp for simd' after parsing of the associated statement.
DeclContext * getCurLexicalContext() const
OMPClause * ActOnOpenMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_teams' clause.
bool isInOpenMPDeclareTargetContext() const
Return true inside OpenMP declare target region.
bool LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS, bool AllowBuiltinCreation=false, bool EnteringContext=false)
Performs name lookup for a name that was parsed in the source code, and may contain a C++ scope speci...
void ActOnOpenMPDeclareTargetName(NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, DeclareTargetContextInfo &DTCI)
Called on correct id-expression from the '#pragma omp declare target'.
OMPClause * ActOnOpenMPDefaultClause(llvm::omp::DefaultKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'default' clause.
ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op)
void ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, CapturedRegionKind Kind, unsigned NumParams)
OMPClause * ActOnOpenMPNocontextClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'nocontext' clause.
StmtResult ActOnOpenMPMasterTaskLoopSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp master taskloop simd' after parsing of the associated statement.
sema::FunctionScopeInfo * getCurFunction() const
OMPClause * ActOnOpenMPAlignedClause(ArrayRef< Expr * > VarList, Expr *Alignment, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'aligned' clause.
StmtResult ActOnOpenMPTargetTeamsDistributeParallelForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams distribute parallel for' after parsing of the associa...
StmtResult ActOnOpenMPParallelSectionsDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp parallel sections' after parsing of the associated statement.
StmtResult ActOnOpenMPTargetEnterDataDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AStmt)
Called on well-formed '#pragma omp target enter data' after parsing of the associated statement.
OMPClause * ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation NameModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'if' clause.
ExprResult ActOnOpenMPCall(ExprResult Call, Scope *Scope, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig)
Given the potential call expression Call, determine if there is a specialization via the OpenMP decla...
StmtResult ActOnOpenMPTargetTeamsDistributeDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams distribute' after parsing of the associated statement...
OMPClause * ActOnOpenMPUsesAllocatorClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< UsesAllocatorsData > Data)
Called on well-formed 'uses_allocators' clause.
OMPClause * ActOnOpenMPOrderedClause(SourceLocation StartLoc, SourceLocation EndLoc, SourceLocation LParenLoc=SourceLocation(), Expr *NumForLoops=nullptr)
Called on well-formed 'ordered' clause.
StmtResult ActOnOpenMPParallelMaskedTaskLoopSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel masked taskloop simd' after parsing of the associated sta...
StmtResult ActOnOpenMPTaskDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp task' after parsing of the associated statement.
ExprResult DefaultLvalueConversion(Expr *E)
bool isVisible(const NamedDecl *D)
Determine whether a declaration is visible to name lookup.
StmtResult ActOnOpenMPUnrollDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp unroll' after parsing of its clauses and the associated statement.
QualType ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, TypeResult ParsedType)
Check if the specified type is allowed to be used in 'omp declare reduction' construct.
OMPClause * ActOnOpenMPMergeableClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'mergeable' clause.
sema::BlockScopeInfo * getCurBlock()
Retrieve the current block, if any.
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope)
Initialization of captured region for OpenMP region.
bool CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, OpenMPLinearClauseKind LinKind, QualType Type, bool IsDeclareSimd=false)
Checks that the specified declaration matches requirements for the linear decls.
StmtResult ActOnOpenMPDistributeDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute' after parsing of the associated statement.
VarDecl * ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D)
Initialize declare reduction construct initializer.
void ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D)
Act on D, a function definition inside of an omp [begin/end] assumes.
StmtResult ActOnOpenMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp barrier'.
bool tryCaptureVariable(VarDecl *Var, SourceLocation Loc, TryCaptureKind Kind, SourceLocation EllipsisLoc, bool BuildAndDiagnose, QualType &CaptureType, QualType &DeclRefType, const unsigned *const FunctionScopeIndexToStopAt)
Try to capture the given variable.
StmtResult ActOnOpenMPMasterDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp master' after parsing of the associated statement.
StmtResult ActOnOpenMPTaskgroupDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskgroup'.
OMPClause * ActOnOpenMPReleaseClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'release' clause.
OMPClause * ActOnOpenMPCopyinClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'copyin' clause.
StmtResult ActOnCapturedRegionEnd(Stmt *S)
StmtResult ActOnOpenMPTargetTeamsDistributeSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams distribute simd' after parsing of the associated stat...
StmtResult ActOnOpenMPCriticalDirective(const DeclarationNameInfo &DirName, ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp critical' after parsing of the associated statement.
StmtResult ActOnOpenMPParallelMaskedDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp parallel masked' after parsing of the associated statement.
OMPClause * ActOnOpenMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Called on well-formed 'dist_schedule' clause.
ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E)
void ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, VarDecl *OmpPrivParm)
Finish current declare reduction construct initializer.
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
StmtResult ActOnOpenMPMaskedDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp masked' after parsing of the.
OMPClause * ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)
Called on well-formed 'use' clause.
OMPClause * ActOnOpenMPFullClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-form 'full' clauses.
void ActOnOpenMPEndDeclareVariant()
Handle a omp end declare variant.
@ TryCapture_ExplicitByVal
StmtResult ActOnOpenMPTeamsDistributeDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams distribute' after parsing of the associated statement.
ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *Input)
OMPClause * ActOnOpenMPCompareClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'compare' clause.
bool areMultiversionVariantFunctionsCompatible(const FunctionDecl *OldFD, const FunctionDecl *NewFD, const PartialDiagnostic &NoProtoDiagID, const PartialDiagnosticAt &NoteCausedDiagIDAt, const PartialDiagnosticAt &NoSupportDiagIDAt, const PartialDiagnosticAt &DiffDiagIDAt, bool TemplatesSupported, bool ConstexprSupported, bool CLinkageMayDiffer)
Checks if the variant/multiversion functions are compatible.
OMPClause * ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'detach' clause.
ExprResult ActOnConditionalOp(SourceLocation QuestionLoc, SourceLocation ColonLoc, Expr *CondExpr, Expr *LHSExpr, Expr *RHSExpr)
ActOnConditionalOp - Parse a ?: operation.
StmtResult ActOnOpenMPTargetParallelGenericLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target parallel loop' after parsing of the associated statement.
StmtResult ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, OpenMPDirectiveKind CancelRegion, ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
void ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParameterLists, SmallVectorImpl< FunctionDecl * > &Bases)
The declarator D defines a function in the scope S which is nested in an omp begin/end declare varian...
DeclGroupPtrTy ActOnOpenMPDeclareMapperDirective(Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, Expr *MapperVarRef, ArrayRef< OMPClause * > Clauses, Decl *PrevDeclInScope=nullptr)
Called on start of '#pragma omp declare mapper'.
StmtResult ActOnOpenMPTargetParallelForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target parallel for simd' after parsing of the associated statemen...
llvm::SmallDenseMap< const ValueDecl *, const Expr *, 4 > VarsWithInheritedDSAType
NamedDecl * lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id)
Searches for the provided declaration name for OpenMP declare target directive.
StmtResult ActOnOpenMPSectionDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp section' after parsing of the associated statement.
DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveEnd(Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid)
Called at the end of '#pragma omp declare reduction'.
void ActOnOpenMPBeginDeclareVariant(SourceLocation Loc, OMPTraitInfo &TI)
Handle a omp begin declare variant.
bool isCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind=CompleteTypeKind::Default)
VarDecl * isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo=false, unsigned StopAt=0)
Check if the specified variable is used in one of the private clauses (private, firstprivate,...
@ Private
The private module fragment, between 'module :private;' and the end of the translation unit.
void ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, Expr *VariantRef, OMPTraitInfo &TI, ArrayRef< Expr * > AdjustArgsNothing, ArrayRef< Expr * > AdjustArgsNeedDevicePtr, ArrayRef< OMPDeclareVariantAttr::InteropType > AppendArgs, SourceLocation AdjustArgsLoc, SourceLocation AppendArgsLoc, SourceRange SR)
Called on well-formed '#pragma omp declare variant' after parsing of the associated method/function.
void setFunctionHasBranchProtectedScope()
OMPClause * ActOnOpenMPCopyprivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'copyprivate' clause.
OMPClause * ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'depobj' pseudo clause.
QualType ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, TypeResult ParsedType)
Check if the specified type is allowed to be used in 'omp declare mapper' construct.
OMPClause * ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'thread_limit' clause.
bool ActOnStartOpenMPDeclareTargetContext(DeclareTargetContextInfo &DTCI)
Called on the start of target region i.e. '#pragma omp declare target'.
const DeclareTargetContextInfo ActOnOpenMPEndDeclareTargetDirective()
Called at the end of target region i.e. '#pragma omp end declare target'.
void StartOpenMPClause(OpenMPClauseKind K)
Start analysis of clauses.
OMPClause * ActOnOpenMPPrivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'private' clause.
StmtResult ActOnOpenMPDispatchDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp dispatch' after parsing of the.
OMPClause * ActOnOpenMPNontemporalClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'nontemporal' clause.
OMPClause * ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'unified_address' clause.
bool isInOpenMPTargetExecutionDirective() const
Return true inside OpenMP target region.
Optional< std::pair< FunctionDecl *, Expr * > > checkOpenMPDeclareVariantFunction(DeclGroupPtrTy DG, Expr *VariantRef, OMPTraitInfo &TI, unsigned NumAppendArgs, SourceRange SR)
Checks '#pragma omp declare variant' variant function and original functions after parsing of the ass...
ExprResult CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, Expr *Idx, SourceLocation RLoc)
StmtResult ActOnOpenMPTeamsGenericLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams loop' after parsing of the associated statement.
OMPClause * ActOnOpenMPThreadsClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'threads' clause.
OMPClause * ActOnOpenMPAtomicDefaultMemOrderClause(OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'atomic_default_mem_order' clause.
@ PotentiallyEvaluated
The current expression is potentially evaluated at run time, which means that code may be generated t...
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
void diagnoseTypo(const TypoCorrection &Correction, const PartialDiagnostic &TypoDiag, bool ErrorRecovery=true)
OMPClause * ActOnOpenMPNumTasksClause(Expr *NumTasks, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_tasks' clause.
StmtResult ActOnDeclStmt(DeclGroupPtrTy Decl, SourceLocation StartLoc, SourceLocation EndLoc)
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
Scope * TUScope
Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
StmtResult ActOnOpenMPTargetTeamsGenericLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams loop' after parsing of the associated statement.
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
OMPClause * ActOnOpenMPReadClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'read' clause.
StmtResult ActOnOpenMPTaskLoopSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp taskloop simd' after parsing of the associated statement.
StmtResult ActOnOpenMPSectionsDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp sections' after parsing of the associated statement.
void StartOpenMPDSABlock(OpenMPDirectiveKind K, const DeclarationNameInfo &DirName, Scope *CurScope, SourceLocation Loc)
Called on start of new data sharing attribute block.
void DiscardCleanupsInEvaluationContext()
void PushDeclContext(Scope *S, DeclContext *DC)
Set the current declaration context until it gets popped.
StmtResult ActOnOpenMPParallelForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel for' after parsing of the associated statement.
bool isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, unsigned OpenMPCaptureLevel) const
Return true if the provided declaration VD should be captured by reference.
MemberExpr * BuildMemberExpr(Expr *Base, bool IsArrow, SourceLocation OpLoc, const CXXScopeSpec *SS, SourceLocation TemplateKWLoc, ValueDecl *Member, DeclAccessPair FoundDecl, bool HadMultipleCandidates, const DeclarationNameInfo &MemberNameInfo, QualType Ty, ExprValueKind VK, ExprObjectKind OK, const TemplateArgumentListInfo *TemplateArgs=nullptr)
StmtResult ActOnOpenMPTeamsDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp teams' after parsing of the associated statement.
OMPClause * ActOnOpenMPPartialClause(Expr *FactorExpr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-form 'partial' clauses.
OMPClause * ActOnOpenMPSafelenClause(Expr *Length, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'safelen' clause.
RedeclarationKind forRedeclarationInCurContext()
ExprResult DefaultFunctionArrayConversion(Expr *E, bool Diagnose=true)
DefaultFunctionArrayConversion (C99 6.3.2.1p3, C99 6.3.2.1p4).
ExprResult getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, ExprObjectKind OK, SourceLocation Loc)
StmtResult ActOnOpenMPAtomicDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp atomic' after parsing of the associated statement.
void EndOpenMPDSABlock(Stmt *CurDirective)
Called on end of data sharing attribute block.
OMPClause * ActOnOpenMPNogroupClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'nogroup' clause.
StmtResult ActOnOpenMPParallelDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp parallel' after parsing of the associated statement.
void FilterLookupForScope(LookupResult &R, DeclContext *Ctx, Scope *S, bool ConsiderLinkage, bool AllowInlineNamespace)
Filters out lookup results that don't fall within the given scope as determined by isDeclInScope.
StmtResult ActOnOpenMPTileDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp tile' after parsing of its clauses and the associated statement.
StmtResult ActOnOpenMPParallelGenericLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel loop' after parsing of the associated statement.
void ActOnUninitializedDecl(Decl *dcl)
StmtResult ActOnOpenMPTaskLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp taskloop' after parsing of the associated statement.
void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit)
AddInitializerToDecl - Adds the initializer Init to the declaration dcl.
StmtResult ActOnOpenMPTeamsDistributeSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams distribute simd' after parsing of the associated statement.
OMPClause * ActOnOpenMPFromClause(ArrayRef< OpenMPMotionModifierKind > MotionModifiers, ArrayRef< SourceLocation > MotionModifiersLoc, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs, ArrayRef< Expr * > UnresolvedMappers=llvm::None)
Called on well-formed 'from' clause.
OMPClause * ActOnOpenMPLastprivateClause(ArrayRef< Expr * > VarList, OpenMPLastprivateModifier LPKind, SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'lastprivate' clause.
OMPClause * ActOnOpenMPReductionClause(ArrayRef< Expr * > VarList, OpenMPReductionClauseModifier Modifier, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr * > UnresolvedReductions=llvm::None)
Called on well-formed 'reduction' clause.
void ActOnOpenMPAssumesDirective(SourceLocation Loc, OpenMPDirectiveKind DKind, ArrayRef< std::string > Assumptions, bool SkippedClauses)
Called on well-formed '#pragma omp [begin] assume[s]'.
OMPClause * ActOnOpenMPSizesClause(ArrayRef< Expr * > SizeExprs, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-form 'sizes' clause.
FunctionDecl * getCurFunctionDecl(bool AllowLambda=false)
Returns a pointer to the innermost enclosing function, or nullptr if the current context is not insid...
OMPClause * ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'order' clause.
void EndOpenMPClause()
End analysis of clauses.
bool isOpenMPRebuildMemberExpr(ValueDecl *D)
The member expression(this->fd) needs to be rebuilt in the template instantiation to generate private...
StmtResult ActOnOpenMPGenericLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp loop' after parsing of the associated statement.
ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
TypeSourceInfo * GetTypeForDeclarator(Declarator &D, Scope *S)
GetTypeForDeclarator - Convert the type for the specified declarator to Type instances.
StmtResult ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskyield'.
OMPClause * ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'reverse_offload' clause.
ExprResult CreateBuiltinBinOp(SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
CreateBuiltinBinOp - Creates a new built-in binary operation with operator Opc at location TokLoc.
StmtResult ActOnOpenMPTeamsDistributeParallelForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams distribute parallel for simd' after parsing of the associate...
bool IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base)
Determine whether the type Derived is a C++ class that is derived from the type Base.
OMPClause * ActOnOpenMPTaskReductionClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr * > UnresolvedReductions=llvm::None)
Called on well-formed 'task_reduction' clause.
sema::FunctionScopeInfo * getEnclosingFunction() const
StmtResult ActOnOpenMPMasterTaskLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp master taskloop' after parsing of the associated statement.
sema::CapturedRegionScopeInfo * getCurCapturedRegion()
Retrieve the current captured region, if any.
bool CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, SourceLocation LinLoc)
Checks correctness of linear modifiers.
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
static QualType GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo=nullptr)
void ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner)
Finish current declare reduction construct initializer.
ExprResult CreateBuiltinUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *InputExpr)
OMPClause * ActOnOpenMPDefaultmapClause(OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, SourceLocation KindLoc, SourceLocation EndLoc)
Called on well-formed 'defaultmap' clause.
StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R, ArrayRef< Stmt * > Elts, bool isStmtExpr)
StmtResult ActOnOpenMPCanonicalLoop(Stmt *AStmt)
Called for syntactical loops (ForStmt or CXXForRangeStmt) associated to an OpenMP loop directive.
StmtResult ActOnOpenMPParallelMasterTaskLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel master taskloop' after parsing of the associated statemen...
StmtResult ActOnOpenMPTeamsDistributeParallelForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams distribute parallel for' after parsing of the associated sta...
OMPClause * ActOnOpenMPInclusiveClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'inclusive' clause.
StmtResult ActOnOpenMPParallelForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel for simd' after parsing of the associated statement.
OpenMPClauseKind isOpenMPPrivateDecl(ValueDecl *D, unsigned Level, unsigned CapLevel) const
Check if the specified variable is used in 'private' clause.
FullExprArg MakeFullExpr(Expr *Arg)
OMPClause * ActOnOpenMPCollapseClause(Expr *NumForLoops, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'collapse' clause.
bool isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level, unsigned CaptureLevel) const
Check if the specified variable is captured by 'target' directive.
OMPRequiresDecl * CheckOMPRequiresDecl(SourceLocation Loc, ArrayRef< OMPClause * > Clauses)
Check restrictions on Requires directive.
OMPClause * ActOnOpenMPIsDevicePtrClause(ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs)
Called on well-formed 'is_device_ptr' clause.
StmtResult ActOnOpenMPTargetDataDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target data' after parsing of the associated statement.
OMPClause * ActOnOpenMPAllocatorClause(Expr *Allocator, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'allocator' clause.
OMPClause * ActOnOpenMPInReductionClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr * > UnresolvedReductions=llvm::None)
Called on well-formed 'in_reduction' clause.
StmtResult ActOnOpenMPSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp simd' after parsing of the associated statement.
SemaDiagnosticBuilder targetDiag(SourceLocation Loc, unsigned DiagID, FunctionDecl *FD=nullptr)
void ActOnFinishedOpenMPDeclareTargetContext(DeclareTargetContextInfo &DTCI)
Called once a target context is completed, that can be when a '#pragma omp end declare target' was en...
ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue)
OMPClause * ActOnOpenMPRelaxedClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'relaxed' clause.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
A trivial tuple used to represent a source range.
void setBegin(SourceLocation b)
SourceLocation getBegin() const
void setEnd(SourceLocation e)
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Stmt - This represents one statement.
SourceLocation getEndLoc() const LLVM_READONLY
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical) const
Produce a unique representation of the given statement.
Stmt * IgnoreContainers(bool IgnoreCaptured=false)
Skip no-op (attributed, compound) container stmts and skip captured stmt at the top,...
SourceLocation getBeginLoc() const LLVM_READONLY
bool isTLSSupported() const
Whether the target supports thread-local storage.
bool isVLASupported() const
Whether target supports variable-length arrays.
Represents a declaration of a type.
A container of type source information.
QualType getType() const
Return the type wrapped by this type source info.
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool hasIntegerRepresentation() const
Determine whether this type has an integer representation of some sort, e.g., it is an integer type o...
bool isArithmeticType() const
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
bool isScalarType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool hasUnsignedIntegerRepresentation() const
Determine whether this type has an unsigned integer representation of some sort, e....
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool isAnyComplexType() const
bool containsUnexpandedParameterPack() const
Whether this type is or contains an unexpanded parameter pack, used to support C++0x variadic templat...
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g....
bool isFunctionProtoType() const
bool isOverloadableType() const
Determines whether this is a type for which one can define an overloaded operator.
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
const T * getAsAdjusted() const
Member-template getAsAdjusted<specific type>.
bool isFunctionType() const
bool isStructureOrClassType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
bool isAnyPointerType() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
bool isFunctionNoProtoType() const
Simple class containing the result of Sema::CorrectTypo.
NamedDecl * getCorrectionDecl() const
Gets the pointer to the declaration of the typo correction.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
static UnresolvedLookupExpr * Create(const ASTContext &Context, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, bool RequiresADL, bool Overloaded, UnresolvedSetIterator Begin, UnresolvedSetIterator End)
void append(iterator I, iterator E)
void addDecl(NamedDecl *D)
A set of unresolved declarations.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
void setType(QualType newType)
Represents a variable declaration or definition.
static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)
bool isFunctionOrMethodVarDecl() const
Similar to isLocalVarDecl, but excludes variables declared in blocks.
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
TLSKind getTLSKind() const
void setInitStyle(InitializationStyle Style)
InitializationStyle getInitStyle() const
The style of initialization for this declaration.
DefinitionKind isThisDeclarationADefinition(ASTContext &) const
Check whether this declaration is a definition.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
@ CInit
C-style initialization with assignment.
@ CallInit
Call-style initialization (C++98)
bool isStaticDataMember() const
Determines whether this is a static data member.
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
bool isFileVarDecl() const
Returns true for file scoped variable declaration.
const Expr * getInit() const
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
@ TLS_None
Not a TLS variable.
@ DeclarationOnly
This declaration is only a declaration.
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
bool isDirectInit() const
Whether the initializer is a direct-initializer (list or call).
StorageDuration getStorageDuration() const
Get the storage duration of this variable, per C++ [basic.stc].
StorageClass getStorageClass() const
Returns the storage class as written in the source.
bool isUsableInConstantExpressions(const ASTContext &C) const
Determine whether this variable's value can be used in a constant expression, according to the releva...
bool isLocalVarDeclOrParm() const
Similar to isLocalVarDecl but also includes parameters.
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
Directive - Abstract class representing a parsed verify directive.
Retains information about a captured region.
unsigned short OpenMPLevel
unsigned short OpenMPCaptureLevel
Retains information about a function, method, or block that is currently being parsed.
void setHasOMPDeclareReductionCombiner()
SmallVector< CompoundScopeInfo, 4 > CompoundScopes
The stack of currently active compound stamement scopes in the function.
specific_attr_iterator - Iterates over a subrange of an AttrVec, only providing attributes that are o...
Defines the clang::TargetInfo interface.
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
bool LE(InterpState &S, CodePtr OpPC)
bool isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a worksharing directive.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ OO_None
Not an overloaded operator.
@ NUM_OVERLOADED_OPERATORS
bool isOpenMPNestingTeamsDirective(OpenMPDirectiveKind DKind)
Checks if the specified composite/combined directive constitutes a teams directive in the outermost n...
bool isa(CodeGen::Address addr)
bool isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a target data offload directive.
bool isOpenMPLoopTransformationDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a loop transformation directive.
OpenMPDefaultmapClauseModifier
OpenMP modifiers for 'defaultmap' clause.
@ OMPC_DEFAULTMAP_MODIFIER_last
@ OMPC_DEFAULTMAP_MODIFIER_unknown
ExprObjectKind
A further classification of the kind of object referenced by an l-value or x-value.
@ OK_Ordinary
An ordinary object is located at an address in memory.
Expr * AssertSuccess(ExprResult R)
bool isOpenMPDistributeDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a distribute directive.
@ LCK_ByRef
Capturing by reference.
@ LCK_This
Capturing the *this object by reference.
OpenMPReductionClauseModifier
OpenMP modifiers for 'reduction' clause.
OpenMPScheduleClauseModifier
OpenMP modifiers for 'schedule' clause.
@ OMPC_SCHEDULE_MODIFIER_last
@ OMPC_SCHEDULE_MODIFIER_unknown
const char * getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type)
bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a parallel-kind directive.
bool isOpenMPPrivate(OpenMPClauseKind Kind)
Checks if the specified clause is one of private clauses like 'private', 'firstprivate',...
OpenMPDistScheduleClauseKind
OpenMP attributes for 'dist_schedule' clause.
@ OMPC_DIST_SCHEDULE_unknown
static constexpr StringRef getOpenMPVariantManglingSeparatorStr()
OpenMP variants are mangled early based on their OpenMP context selector.
bool isOpenMPTaskingDirective(OpenMPDirectiveKind Kind)
Checks if the specified directive kind is one of tasking directives - task, taskloop,...
static constexpr unsigned NumberOfOMPMapClauseModifiers
Number of allowed map-type-modifiers.
bool isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a target code offload directive.
@ C
Languages that the frontend can parse and compile.
@ SD_Static
Static storage duration.
@ Result
The result type of a method or function.
bool isOpenMPTeamsDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a teams-kind directive.
bool isOpenMPGenericLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive constitutes a 'loop' directive in the outermost nest.
OpenMPBindClauseKind
OpenMP bindings for the 'bind' clause.
OpenMPLastprivateModifier
OpenMP 'lastprivate' clause modifier.
@ OMPC_LASTPRIVATE_unknown
OpenMPDependClauseKind
OpenMP attributes for 'depend' clause.
bool IsXLHSInRHSPart
True if UE has the first form and false if the second.
bool IsPostfixUpdate
True if original value of 'x' must be stored in 'v', not an updated one.
bool isOpenMPLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a directive with an associated loop construct.
bool isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind)
Checks if the specified directive kind is one of the composite or combined directives that need loop ...
static constexpr unsigned NumberOfOMPMotionModifiers
Number of allowed motion-modifiers.
OpenMPMotionModifierKind
OpenMP modifier kind for 'to' or 'from' clause.
@ OMPC_MOTION_MODIFIER_unknown
OpenMPDefaultmapClauseKind
OpenMP attributes for 'defaultmap' clause.
@ OMPC_DEFAULTMAP_unknown
bool isOpenMPThreadPrivate(OpenMPClauseKind Kind)
Checks if the specified clause is one of threadprivate clauses like 'threadprivate',...
OpenMPLinearClauseKind
OpenMP attributes for 'linear' clause.
llvm::omp::Directive OpenMPDirectiveKind
OpenMP directives.
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a simd directive.
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
void getOpenMPCaptureRegions(llvm::SmallVectorImpl< OpenMPDirectiveKind > &CaptureRegions, OpenMPDirectiveKind DKind)
Return the captured regions of an OpenMP directive.
OpenMPAtomicDefaultMemOrderClauseKind
OpenMP attributes for 'atomic_default_mem_order' clause.
@ OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown
bool IsFailOnly
True if 'v' is updated only when the condition is false (compare capture only).
U cast(CodeGen::Address addr)
@ None
The alignment was not explicit in code.
OpenMPDeviceClauseModifier
OpenMP modifiers for 'device' clause.
OpenMPMapModifierKind
OpenMP modifier kind for 'map' clause.
@ OMPC_MAP_MODIFIER_unknown
llvm::omp::Clause OpenMPClauseKind
OpenMP clauses.
bool isOpenMPNestingDistributeDirective(OpenMPDirectiveKind DKind)
Checks if the specified composite/combined directive constitutes a distribute directive in the outerm...
ActionResult< Expr * > ExprResult
OpenMPOrderClauseKind
OpenMP attributes for 'order' clause.
OpenMPScheduleClauseKind
OpenMP attributes for 'schedule' clause.
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a taskloop directive.
OpenMPMapClauseKind
OpenMP mapping kind for 'map' clause.
unsigned operator()(argument_type DK)
OpenMPDirectiveKind argument_type
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspnd...
SourceLocation getLoc() const
getLoc - Returns the main location of the declaration name.
DeclarationName getName() const
getName - Returns the embedded declaration name.
void setLoc(SourceLocation L)
setLoc - Sets the main location of the declaration name.
void setName(DeclarationName N)
setName - Sets the embedded declaration name.
SourceLocation getBeginLoc() const
getBeginLoc - Retrieve the location of the first token.
std::string getAsString() const
getAsString - Retrieve the human-readable string for this name.
SourceLocation getEndLoc() const LLVM_READONLY
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
Extra information about a function prototype.
SourceLocation OmpAllMemoryLoc
Location of 'omp_all_memory'.
SourceLocation ColonLoc
Colon location.
OpenMPDependClauseKind DepKind
Dependency type (one of in, out, inout).
SourceLocation DepLoc
Dependency type location.
Data for list of allocators.
SourceLocation LParenLoc
Locations of '(' and ')' symbols.
Expr * AllocatorTraits
Allocator traits.
Expr * Allocator
Allocator.
This structure contains most locations needed for by an OMPVarListClause.
SourceLocation StartLoc
Starting location of the clause (the clause keyword).
SourceLocation LParenLoc
Location of '('.
SourceLocation EndLoc
Ending location of the clause.
Data used for processing a list of variables in OpenMP clauses.
CXXScopeSpec ReductionOrMapperIdScopeSpec
SmallVector< OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers > MapTypeModifiers
SmallVector< OpenMPMotionModifierKind, NumberOfOMPMotionModifiers > MotionModifiers
SourceLocation ExtraModifierLoc
DeclarationNameInfo ReductionOrMapperId
SmallVector< SourceLocation, NumberOfOMPMotionModifiers > MotionModifiersLoc
SourceLocation OmpAllMemoryLoc
SmallVector< SourceLocation, NumberOfOMPMapClauseModifiers > MapTypeModifiersLoc
int ExtraModifier
Additional modifier for linear, map, depend or lastprivate clause.
Data for list of allocators.
Expr * Allocator
Allocator.
SourceLocation LParenLoc
Locations of '(' and ')' symbols.
Expr * AllocatorTraits
Allocator traits.
Clang specific specialization of the OMPContext to lookup target features.